在Scala代码中,我想创建一个解释器,该解释器将评估一些Scala代码的字符串,例如,使用ScriptEngine。但是我想将当前变量和类型定义传递给它,以便字符串中的代码可以使用它们,就像新解释器是从当前解释器派生的一样。
使用ScriptEngine,我可以使用“ put”方法将绑定放入其中,但这对于每个变量都必须是明确的。而且,无法传递类定义或方法等。
那有办法吗,还是我误会了什么?
目的是让动态代码使用准备好的数据和方法
这是我现在可以做的:
import javax.script._
val e = new ScriptEngineManager().getEngineByName("scala")
engine.put("x", 123)
engine.eval("val y = x.asInstanceOf[Int] + 100")
这就是我想要做的:
case class X(a: Int, b: Int)
val x = X(1,2)
engine.eval("val x1 = X(x.a + 1, x.b + 1)") // Use both X and x
答案 0 :(得分:0)
您可以尝试
val res = engine.eval(
"""case class X(a: Int, b: Int)
|val x = X(1,2)
|val x1 = X(x.a + 1, x.b + 1)""".stripMargin)
您也可以使用scala.tools.reflect.ToolBox
。
使用导入。
package mypackage
import javax.script._
object App {
val engine = new ScriptEngineManager().getEngineByName("scala")
case class X(a: Int, b: Int)
val x = X(1,2)
val res = engine.eval("import mypackage.App._; val x1 = X(x.a + 1, x.b + 1)")
}
或
package mypackage
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
object App {
val tb = runtimeMirror(ClassLoader.getSystemClassLoader).mkToolBox()
case class X(a: Int, b: Int)
val x = X(1, 2)
val tree = tb.parse("import mypackage.App._; val x1 = X(x.a + 1, x.b + 1)")
val res = tb.eval(tree)
}