Scala: как создать интерпретатор, наследующий текущий контекст?

В коде 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

person user11595225    schedule 07.06.2019    source источник


Ответы (1)


Можешь попробовать

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)")
}

or

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)
}
person Dmytro Mitin    schedule 07.06.2019
comment
Это не так. Это не наследование, а создание контекста заново. - person user11595225; 27.06.2019