What is the best way to inject a snippet of code to scala? something like eval in javascript and GroovyScriptEngine. I want to keep my rules/computations/formulas outside the actual data processing class. I have close to 100+ formulas to be executed. The data flow is same for all only the formulas change. What is the best way to do it in scala? and the number of formulas will grow over time.
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
You could use either scala-lang
API for that or twitter-eval
. Here is the snippet of a simple use case of scala-lang
import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.IMain
object ScalaReflectEvaluator {
def evaluate() = {
val clazz = prepareClass
val settings = new Settings
settings.usejavacp.value = true
settings.deprecation.value = true
val eval = new IMain(settings)
val evaluated = eval.interpret(clazz)
val res = eval.valueOfTerm("res0").get.asInstanceOf[Int]
println(res) //yields 9
}
private def prepareClass: String = {
s"""
|val x = 4
|val y = 5
|x + y
|""".stripMargin
}
}
or with twitter:
import com.twitter.util.Eval
object TwitterUtilEvaluator {
def evaluate() = {
val clazz = prepareClass
val eval = new Eval
eval.apply[Int](clazz)
}
private def prepareClass: String = {
s"""
|val x = 4
|val y = 5
|x + y
|""".stripMargin
}
}
I am not able to compile it at the moment to check whether I have missed something but you should get the idea.
回答2:
I've found that scala.tools.reflect.ToolBox
is the fastest eval in scala (measured interpreter, twitter's eval and custom tool). It's API:
import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
tb.eval(tb.parse("""println("hello!")"""))