2016-08-25 129 views
2

將一段代碼注入scala的最佳方式是什麼?像JavaScript和GroovyScriptEngine中的eval。我想保留我的規則/計算/公式以外的實際數據處理類。我有接近100+的公式被執行。所有數據流都相同,只有公式發生變化。什麼是最好的方式來做它在斯卡拉?公式的數量將隨着時間的推移而增長。scala中的動態代碼評估

+1

考慮閱讀這個問題 - https://stackoverflow.com/questions/1183645/eval-in-scala – tuxdna

回答

3

您可以使用該或twitter-eval要麼scala-lang API。這裏是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 
    } 
} 

或與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 
    } 
} 

我不能編譯它的那一刻,檢查我是否錯過了一些東西,但你應該得到這個想法。

+0

是可以傳遞給一個變量?所以例如,所以你可以在代碼中使用println(z)來評估​​它,並打印出「test」 – Nicofisi

+0

我認爲你不可以。他們將在不同的運行環境中。所以這不是一個真正的腳本代碼注入。請參閱:JSR-223:https://www.jcp.org/en/jsr/detail?id = 223 – linehrr

2

我發現scala.tools.reflect.ToolBox是Scala最快的eval(測量解釋,Twitter的評估和自定義工具)。它的API:

import scala.reflect.runtime.universe 
import scala.tools.reflect.ToolBox 
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox() 
tb.eval(tb.parse("""println("hello!")"""))