2015-03-31 3 views
3

Я нашел пример кода для сценариев выполнения Scala в ответ на Generating a class from string and instantiating it in Scala 2.10, однако код, кажется, устарел для 2.11 - я не могу найти какую-либо функцию, соответствующую build.setTypeSignature. Даже если это сработало, код, похоже, трудно читать и следить за мной.Scala script в 2.11

Как скрипты Scala могут быть скомпилированы и выполнены в Scala 2.11?

Допустим, я хочу следующее:

  • определить несколько переменных (имена и значения)
  • компиляции сценария
  • (опция улучшения) изменить значения переменных
  • выполнить скрипт

Для простоты рассмотрите следующий пример:

Я хочу определить следующие переменные (программно из кода, а не из текста сценария):

val a = 1 
val s = "String" 

Я хочу следующий скрипт для компиляции и выполнения значение "a is 1, s is String"String возвращается из него:

s"a is $a, s is $s" 

Как должны выглядеть мои функции?

def setupVariables() = ??? 

def compile() = ??? 

def changeVariables() = ??? 

def execute() : String = ??? 
+0

Примечание: 'build.setTypeSignature' был заменен на' internal.reificationSupport.setInfo'. См. Также [Изменения в Scala 2.11] (http://docs.scala-lang.org/overviews/macros/changelog211.html) - пункт ** Как сделать ваши макросы 2.10.x работать в 2.11.0 **. – Suma

ответ

2

Скала 2.11 adds JSR-223 scripting engine. Он должен предоставить вам функциональность, которую вы ищете. Как напоминание, как и все эти виды динамических вещей, включая пример, приведенный в описании выше, вы потеряете безопасность типа. Ниже вы можете видеть, что возвращаемый тип всегда Object.

Скала РЕПЛ Пример:

scala> import javax.script.ScriptEngineManager 

import javax.script.ScriptEngineManager 


scala> val e = new ScriptEngineManager().getEngineByName("scala") 

e: javax.script.ScriptEngine = [email protected] 


scala> e.put("a", 1) 

a: Object = 1 


scala> e.put("s", "String") 

s: Object = String 


scala> e.eval("""s"a is $a, s is $s"""") 

res6: Object = a is 1, s is String` 

Добавка пример, как приложение, работающее под Скале 2.11.6:

import javax.script.ScriptEngineManager 

object EvalTest{ 
    def main(args: Array[String]){ 
    val e = new ScriptEngineManager().getEngineByName("scala") 
    e.put("a", 1) 
    e.put("s", "String") 
    println(e.eval("""s"a is $a, s is $s"""")) 
    } 
} 

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

libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value 
+0

Это выглядит многообещающим, однако, когда я запускаю его в своем приложении (а не REPL), я получаю ошибку 'scala.reflect.internal.MissingRequirementError: объект scala в зеркале компилятора не найден .'. У меня есть все «scala-reflect», «scala-compiler» и «scala-library» в моем файле build.sbt (и на самом деле у меня уже была компиляция скрипта, работающая с использованием 'universe.runtimeMirror', только переменная настройка была чем-то, что я был не в состоянии сделать). – Suma

+0

Примечание: Созданный механизм создания скриптов getEngineByName преуспевает, но я получаю исключение при вызове функции eval. – Suma

+0

Я могу избавиться от исключения, используя 'e.asInstanceOf [IMain] .settings.usejavacp.value = true', но затем я получаю очень странные ошибки при выполнении второго скрипта (' CaseClassException' при передаче 'IMain'' IMain '). Мое дикое предположение о внедрении Scala в стиле JSR-223 предназначено для приложений Java, а не для Scala? – Suma

Смежные вопросы