使Scala解释器在解释调用之间不被察觉
是否可以配置Scala解释器(使Scala解释器在解释调用之间不被察觉,scala,compiler-construction,classloader,interpreter,Scala,Compiler Construction,Classloader,Interpreter,是否可以配置Scala解释器(tools.nsc.IMain),以便每当我运行下一个exploration()调用时,它“忘记”以前执行的代码? 通常,当它编译源代码时,会将它们封装在嵌套对象中,因此所有以前定义的变量、函数和绑定都可用 不生成嵌套对象(或扔掉它们)就足够了,尽管我更喜欢一种解决方案,它甚至可以再次从类装入器中删除以前编译过的类 是否有一种设置、方法或我可以覆盖的内容,或是IMain的替代方案可以实现这一点?我需要仍然能够从主机VM访问生成的对象/类 基本上,我想隔离后续的ex
tools.nsc.IMain
),以便每当我运行下一个exploration()
调用时,它“忘记”以前执行的代码?
通常,当它编译源代码时,会将它们封装在嵌套对象中,因此所有以前定义的变量、函数和绑定都可用
不生成嵌套对象(或扔掉它们)就足够了,尽管我更喜欢一种解决方案,它甚至可以再次从类装入器中删除以前编译过的类
是否有一种设置、方法或我可以覆盖的内容,或是IMain
的替代方案可以实现这一点?我需要仍然能够从主机VM访问生成的对象/类
基本上,我想隔离后续的
explorate()
调用,而不需要为每个迭代创建一个新的IMain
。这里是一个可能的答案。基本上有一个方法reset()
,它调用以下内容(大部分是私有的,因此您可以购买整个软件包,也可以不购买):
在我的例子中,我使用的是一个自定义的执行包装器,因此需要再次设置它,并且导入也通过一个常规的解释周期来处理,所以要么再次添加它们,要么最好使用执行包装器将它们预加
我想保留我的绑定,它们也不见了:
import tools.nsc._
import interpreter.IMain
object Test {
private final class Intp(cset: nsc.Settings)
extends IMain(cset, new NewLinePrintWriter(new ConsoleWriter, autoFlush = true)) {
override protected def parentClassLoader = Test.getClass.getClassLoader
}
object Foo {
def bar() { println("BAR" )}
}
def run() {
val cset = new nsc.Settings()
cset.classpath.value += java.io.File.pathSeparator + sys.props("java.class.path")
val i = new Intp(cset)
i.initializeSynchronous()
i.bind[Foo.type]("foo", Foo)
val res0 = i.interpret("foo.bar(); val x = 33")
println(s"res0: $res0")
i.reset()
val res1 = i.interpret("println(x)")
println(s"res1: $res1")
i.reset()
val res2 = i.interpret("foo.bar()")
println(s"res2: $res2")
}
}
这将在第一次迭代中找到Foo
,在第二次迭代中正确地忘记x
,但在第三次迭代中,可以看到Foo
绑定也丢失了:
foo: Test.Foo.type = Test$Foo$@8bf223
BAR
x: Int = 33
res0: Success
<console>:8: error: not found: value x
println(x)
^
res1: Error
<console>:8: error: not found: value foo
foo.bar()
^
res2: Error
foo:Test.foo.type=Test$foo$@8bf223
酒吧
x:Int=33
res0:成功
:8:错误:未找到:值x
println(x)
^
res1:错误
:8:错误:未找到:值foo
foo.bar()
^
res2:错误
以下几点似乎很好:
for(j <- 0 until 3) {
val user = "foo.bar()"
val synth = """import Test.{Foo => foo}
""".stripMargin + user
val res = i.interpret(synth)
println(s"res$j: $res")
i.reset()
}
(j)的
for(j <- 0 until 3) {
val user = "foo.bar()"
val synth = """import Test.{Foo => foo}
""".stripMargin + user
val res = i.interpret(synth)
println(s"res$j: $res")
i.reset()
}