0

"Использование 'eval' в Scala"

27

Может ли Scala использоваться для скриптинга Java-приложения?

Мне нужно загрузить участок кода на Scala из Java, установить для него контекст выполнения (данные, предоставленные основной программой), оценить его и получить объект результата.

Документация по Scala демонстрирует, насколько легко вызывать скомпилированный код Scala из Java, поскольку он преобразуется в обычный байт-код JVM.

Но как я могу оценивать выражение на Scala "на лету" (из Java или, если это проще, из самой Scala)?

Для многих других языков существует интерфейс javax.scripting. Однако, похоже, что Scala не поддерживает его, и я не смог найти ничего в документации по совместимости Java/Scala, что не полагалось бы на компиляцию заранее.

4 ответ(ов)

0

Scala добавила официальную поддержку JSR-223 в версии 2.11 (https://issues.scala-lang.org/browse/SI-874).

Если после размышлений над доводами, приведенными в уже принятых ответах от Дэниела Спивека (касательно переосмысления необходимости использования этого подхода), вам все еще нужна эта поддержка, то это должно быть официальной альтернативой.

0

Scala не является языком сценариев. Хотя он может выглядеть как сценарный язык, и некоторые могут рекомендовать его для этого, на самом деле он не вписывается в рамки JSR 223, который ориентирован на динамически типизированные языки. В ответ на ваш первоначальный вопрос: у Scala нет функции eval, так же как и у Java. Такая функция не имеет особого смысла для этих языков из-за их статической природы.

Мой совет: пересмотрите свой код так, чтобы вам не понадобилась функция eval (обычно она не нужна, даже в языках, где она есть, как, например, в Ruby). В качестве альтернативы, возможно, вам не следует использовать Scala для этой части вашего приложения. Если вам действительно необходимо использовать eval, попробуйте JRuby. JRuby, Scala и Java прекрасно сочетаются друг с другом. Вам будет достаточно легко разделить свою систему на части: одну на Java, другую на Scala и еще одну (ту, которая требует eval) на Ruby.

0

Я не уверен, что это лучший способ, но я решил эту задачу, используя toolbox.parse и toolbox.eval.

Чтобы выполнить выражение в Scala, необходимо:

  1. Импортировать scala-reflect. Добавьте следующую зависимость в ваш build.sbt:
libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.11.7"
  1. Использовать eval из toolbox:
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox

val toolbox = currentMirror.mkToolBox()

val as = "2*(2+3)"
val result = toolbox.eval(toolbox.parse(as))

println(result.getClass) // выводит class java.lang.Integer
println(result) // выводит 10

Таким образом, вы сможете динамически оценивать строковые выражения в Scala.

0

Вы всегда можете использовать scalac для компиляции Scala-класса, а затем динамически загрузить этот класс. Но, думаю, это не то, что вы ищете.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь