将脚本结果传递给Scala 2.11 ScriptEngine中的主程序

时间:2014-01-16 23:04:05

标签: scriptengine scala-2.11

在2.11 Milestone 7中使用Scala Scripting Engine,如何从脚本引擎中获取类型值?我收到错误消息,如“mypackage.Holler无法转换为mypackage.Holler”。

这是用例(简称为必需品)。我想使用脚本来准备和配置我将在主程序中处理的标准类型的对象。我有一个特点:

package mypackage

trait Holler {
  def shout: Unit
}

我在Scala中有一个用户脚本,保存在文件/home/me/Foo.scala

object Foo extends mypackage.Holler {
  def shout: Unit = println("Hello World!")
}

当我使用IMain.eval(Reader)运行此脚本时,我希望返回对象Foo,因为它是最后一个语句的结果。这是一个程序,包括几个有用的打印输出来运行脚本:

package mypackage

import javax.script.ScriptEngineManager
import scala.tools.nsc.interpreter.IMain

object Runner {
  def main(args: Array[String]): Unit = {
    //  Create the script engine
    val javaxEngine = new ScriptEngineManager().getEngineByName("scala")
    val scalaEngine = javaEngine.asInstanceOf[IMain]

    // Configure script engine to use the Java classpath
    val useJavaClassPath = scalaEngine.settings.usejavacp.tryToSet(List("true"))
    println("Use Java CP? " + useJavaClassPath)

    val script = new java.io.FileReader("/home/me/Foo.scala")
    val result = scalaEngine.eval(script)
    println("Script Result Type: " + result.getClass.getName)
    println("Defined Symbols: " + scalaEngine.definedSymbolList)
    val myHoller = result.asInstanceOf[mypackage.Holler]
  }
}

脚本在脚本引擎下运行得很好。但结果不能归结为霍勒。该程序的输出如下:

Use Java CP? Some(List(true))
Script Result Type: $line3.$read$$iw$$iw$Foo$
Defined Symbols: List(value engine, object iw$Foo)
Exception in thread "main" java.lang.ClassCastException: $line3.$read$$iw$$iw$Foo$ cannot be cast to mypackage.Holler

这告诉我脚本引擎已成功识别类路径,并且正在构造Foo对象。但是脚本中的特性mypackage.Holler(来自公共类路径)与主程序中的特性mypackage.Holler不同。

如果我在脚本中添加以下行:

Foo.shout
val result: Holler = Foo

我明白了:

  • 正在执行的喊叫方法(“Hello World!”打印出来),
  • “result”被添加到已定义符号列表中
  • 结果与Holler类型明显兼容。

我可以将“catcher”对象绑定到脚本引擎。它的代码如下:

package mypackage

class Catcher {
  var item: Holler = null
}

我与

绑定
val mycatcher = new Catcher
scalaEngine.bind("catcher", mycatcher)
scalaEngine.eval("catcher = Foo")

现在,“catcher”出现在脚本引擎的已定义符号列表中,我可以使用捕获器通过

之类的命令进入脚本引擎
scalaScriptEngine.eval("catcher.item = result")

然后我得到奇怪的“编译时间”ClassCastExceptions说:

mypackage.Holler cannot be cast to mypackage.Holler

如果我把捕手中的“项目”设为任何一个,那么在我做之前我不会得到例外

mycatcher.item.asInstanceOf[Holler]

在主程序中。但我仍然得到几乎相同的例外。就好像两个不兼容的类加载器正在使用相同的类路径。那么,从主程序中,我如何访问Foo对象作为Holler的一个实例(它在脚本引擎中明确实现)?

0 个答案:

没有答案