在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
我明白了:
我可以将“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的一个实例(它在脚本引擎中明确实现)?