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

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

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

До сих пор я думал о:

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

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

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

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

1 Ответ

3 голосов
/ 23 сентября 2011

Второй вариант не выглядит сложным. Например, для библиотеки 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, они, вероятно, содержат некоторые замыкания, так что части их кода находятся в анонимных классах, и вам может потребоваться как-то отследить использование этих классов.

...