Подтвердить что ты не робот

Лучшая практика для обнаружения изменений функций в программах Scala?

Я работаю над Scala -уровневым script языком (внутренней DSL), который позволяет пользователям определять несколько функций преобразования данных в файле Scala script. Поскольку применение этих функций может занять несколько часов, я хотел бы кэшировать результаты в базе данных. Пользователям разрешено изменять определение функций преобразования, а также добавлять новые функции. Однако после этого пользователь перезапускает приложение со слегка измененным script, я хотел бы выполнить только те функции, которые были изменены или добавлены. Вопрос в том, как обнаружить эти изменения? Для простоты предположим, что пользователь может адаптировать только файл script, так что любая ссылка на что-то, не определенная в этом script, может считаться неизменной.

В этом случае лучшая практика для обнаружения изменений в таких пользовательских функциях?

До сих пор я хоть о:

  • разбор файла script и вычисление отпечатков пальцев на основе исходного кода определений функций
  • получение байт-кода каждой функции во время выполнения и создание отпечатков пальцев на основе этих данных
  • применение функций к некоторым тестовым данным и вычисление отпечатков пальцев на результатах

Однако все три подхода имеют свои подводные камни.

  • Написание парсера для Scala для извлечения определений функций может быть довольно сложной задачей, особенно если вы хотите обнаружить изменения, которые косвенно влияют на поведение ваших функций (например, если ваша функция вызывает другую (измененную) функцию, определенную в script).
  • Байт-код может быть другим вариантом, но я никогда не работал с этими библиотеками. Таким образом, я понятия не имею, могут ли они решить мою проблему и как они связаны с динамической привязкой Java.
  • Подход с примерами данных, безусловно, самый простой, но имеет недостаток, что различные пользовательские функции могут быть случайно сопоставлены с одним и тем же отпечатком пальца, если они возвращают те же результаты для моих тестовых данных.

У кого-то есть опыт работы с одним из этих "решений" или может предложить мне лучший вариант?

4b9b3361

Ответ 1

Второй вариант не выглядит сложным. Например, библиотека Javassist, получающая байт-код метода, прост как

CtClass c = ClassPool.getDefault().get(className);
for (CtMethod m: c.getDeclaredMethod()) {
    CodeAttribute ca = m.getMethodInfo().getCodeAttribute();
    if (ca != null) { // i.e. if the method is not native
        byte[] byteCode = ca.getCode();
        ...
    }
}

Итак, до тех пор, пока вы предполагаете, что результаты ваших методов зависят только от кода этих методов, это довольно сложно.

UPDATE: С другой стороны, поскольку ваши методы написаны в Scala, они, вероятно, содержат некоторые замыкания, поэтому части их кода находятся в анонимных классах, и вам может понадобиться как-то отслеживать использование этих классов.