2.11中的Scala脚本

2.11中的Scala脚本,scala,reflection,scripting,compilation,Scala,Reflection,Scripting,Compilation,我找到了一个Scala运行时脚本示例代码来回答,但是该代码对于2.11来说似乎已经过时了-我找不到任何与build.setTypeSignature对应的函数。即使它有效,代码似乎很难阅读和理解 Scala脚本如何在Scala 2.11中编译和执行 让我们假设我想要以下内容: 定义几个变量(名称和值) 编译脚本 (可选改进)更改变量值 执行脚本 为简单起见,请考虑以下例子: 我想定义以下变量(以编程方式,从代码中,而不是从脚本文本中): 我希望编译以下脚本,并在执行时从中返回一个字符串值“a

我找到了一个Scala运行时脚本示例代码来回答,但是该代码对于2.11来说似乎已经过时了-我找不到任何与
build.setTypeSignature
对应的函数。即使它有效,代码似乎很难阅读和理解

Scala脚本如何在Scala 2.11中编译和执行

让我们假设我想要以下内容:

  • 定义几个变量(名称和值)
  • 编译脚本
  • (可选改进)更改变量值
  • 执行脚本
为简单起见,请考虑以下例子:

我想定义以下变量(以编程方式,从代码中,而不是从脚本文本中):

我希望编译以下脚本,并在执行时从中返回一个
字符串
“a是1,s是字符串”

s"a is $a, s is $s"
我的函数应该是什么样子

def setupVariables() = ???

def compile() = ???

def changeVariables() = ???

def execute() : String = ???
Scala JSR-223。它应该为您提供所需的功能。作为提醒,与所有这些类型的动态事物一样,包括上面描述中列出的示例,您将失去类型安全性。您可以在下面看到,返回类型始终是Object

Scala REPL示例:

scala> import javax.script.ScriptEngineManager

import javax.script.ScriptEngineManager


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

e: javax.script.ScriptEngine = scala.tools.nsc.interpreter.IMain@566776ad


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`
作为在scala 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

这看起来很有希望,但是当我在我的应用程序(不是REPL)中运行它时,我得到了错误
scala.reflect.internal.MissingRequirementError:在编译器镜像中找不到对象scala。
。我的build.sbt中有所有的“scala reflect”、“scala compiler”和“scala library”(实际上我已经使用
universe.runtimeMirror
,只有变量设置是我无法完成的)。注意:脚本引擎创建的getEngineByName成功,但是我在调用
eval
函数时遇到异常。我可以通过使用
e.asInstanceOf[IMain].settings.usejavacp.value=true
来消除异常,但是在第二次执行脚本时会出现非常奇怪的错误(
CaseClassException
IMain
转换为
IMain
)。我猜测将Scala嵌入JSR-223样式是为了Java应用程序,而不是Scala应用程序?这段代码只是POC。它还将在应用程序中运行。也许您可以提供您的应用程序代码。除了repl代码之外,我还添加了一个示例应用程序。我记得我在某个地方读到过,在Scala的一些早期版本中,脚本引擎出现了问题。可能尝试运行2.11.6?注意:
build.setTypeSignature
已替换为
internal.reificationSupport.setInfo
。另请参见-如何使2.10.x宏在2.11.0中工作的段落。
libraryDependencies +=  "org.scala-lang" % "scala-compiler" % scalaVersion.value