Scala REPL 在开始使用 scala.tools.nsc.interpreter 时崩溃
Scala REPL crashes when started using scala.tools.nsc.interpreter
我正在尝试使用 scala.tools.nsc.interpreter
启用交互式调试(如 Python 的 pdb/ipdb):
val foo = 123
import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.{ ILoop, SimpleReader }
val repl = new ILoop
repl.settings = new Settings
repl.settings.usejavacp.value = true
repl.in = SimpleReader()
repl.createInterpreter()
repl.intp.bind("foo", "Int", foo)
repl.loop()
repl.closeInterpreter()
当运行时,这是我得到的:
$ scala repl.scala
foo: Int = 123
scala> "hello"
java.lang.NullPointerException
at scala.concurrent.Await$$anonfun$ready.apply(package.scala:95)
at scala.concurrent.Await$$anonfun$ready.apply(package.scala:95)
at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53)
at scala.concurrent.Await$.ready(package.scala:95)
at scala.tools.nsc.interpreter.ILoop.processLine(ILoop.scala:402)
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:430)
at Main$$anon.<init>(repl.scala:14)
at Main$.main(repl.scala:1)
at Main.main(repl.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.reflect.internal.util.ScalaClassLoader$$anonfun$run.apply(ScalaClassLoader.scala:70)
at scala.reflect.internal.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:101)
at scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:70)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
at scala.tools.nsc.ScriptRunner.scala$tools$nsc$ScriptRunner$$runCompiled(ScriptRunner.scala:175)
at scala.tools.nsc.ScriptRunner$$anonfun$runScript.apply(ScriptRunner.scala:192)
at scala.tools.nsc.ScriptRunner$$anonfun$runScript.apply(ScriptRunner.scala:192)
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$$anonfun$apply$mcZ$sp.apply(ScriptRunner.scala:161)
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript.apply$mcZ$sp(ScriptRunner.scala:161)
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript.apply(ScriptRunner.scala:129)
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript.apply(ScriptRunner.scala:129)
at scala.tools.nsc.util.package$.trackingThreads(package.scala:43)
at scala.tools.nsc.util.package$.waitingForThreads(package.scala:27)
at scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:128)
at scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:192)
at scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:205)
at scala.tools.nsc.MainGenericRunner.runTarget(MainGenericRunner.scala:67)
at scala.tools.nsc.MainGenericRunner.run(MainGenericRunner.scala:87)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:98)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Abandoning crashed session.
scala>
如果我删除 repl.intp.bind("foo", "Int", foo)
部分,这就是我得到的:
$ scala repl.scala
scala> 123
null
Abandoning crashed session.
scala>
我做错了什么?有没有更简单的方法可以在程序 运行 期间进入交互式 REPL 进行调试?断点、单步执行和检查局部变量有时不会这样做。
我正在使用 Scala 2.11.5。
我不知道为什么这个评论没有魔法星号:
// start an interpreter with the given settings
def process(settings: Settings): Boolean
所以你可以:
scala> repl process s
Welcome to Scala version 2.11.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :quit
res0: Boolean = true
或者您可以:
package myrepl
import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.{ ILoop, SimpleReader }
object Test extends App {
val foo = 42
val repl = new ILoop {
override def printWelcome() = {
intp.bind("foo", foo)
super.printWelcome()
echo("Customized...")
}
}
val s = new Settings
s.usejavacp.value = true
repl.in = SimpleReader()
repl process s
/*
repl.createInterpreter()
repl.intp.bind("foo", "Int", foo)
repl.loop()
repl.closeInterpreter()
*/
}
和
$ scalac myrepl.scala && scala myrepl.Test
foo: Int = 42
Welcome to Scala version 2.11.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_20).
Type in expressions to have them evaluated.
Type :help for more information.
Customized...
scala> foo
res0: Int = 42
scala> :quit
此外,
s.Xnojline.value = true
//repl.in = SimpleReader()
由于 repl 崩溃错误,我将降级到 2.11.4...
Sbt 通过 overriding createInterpreter
and calling bind there 完成。
编辑:
val repl = new ILoop {
override def printWelcome() = {
//import scala.concurrent.duration._
//Await.ready(globalFuture, 10.minutes) // sorry, it's private!
super.printWelcome()
echo("Customizing...")
processLine("") // block for init to finish
intp.bind("foo", foo)
}
}
私有 globalFuture
是爆炸启动的障碍:
object Solid extends App {
val foo = 42
val repl = new ILoop {
override def printWelcome() = {
super.printWelcome()
echo("Customized...")
}
}
val s = new Settings
s.Xnojline.value = true
s.usejavacp.value = true
repl.settings = s
repl.createInterpreter()
repl.in = SimpleReader()
repl.intp.initializeSynchronous()
repl.loopPostInit()
repl.globalFuture = concurrent.Future.successful(true)
repl.intp.bind("foo", "Int", foo)
try repl.loop()
finally repl.closeInterpreter()
}
2.11 中不再支持 -Yrepl-sync
选项。
我正在尝试使用 scala.tools.nsc.interpreter
启用交互式调试(如 Python 的 pdb/ipdb):
val foo = 123
import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.{ ILoop, SimpleReader }
val repl = new ILoop
repl.settings = new Settings
repl.settings.usejavacp.value = true
repl.in = SimpleReader()
repl.createInterpreter()
repl.intp.bind("foo", "Int", foo)
repl.loop()
repl.closeInterpreter()
当运行时,这是我得到的:
$ scala repl.scala
foo: Int = 123
scala> "hello"
java.lang.NullPointerException
at scala.concurrent.Await$$anonfun$ready.apply(package.scala:95)
at scala.concurrent.Await$$anonfun$ready.apply(package.scala:95)
at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53)
at scala.concurrent.Await$.ready(package.scala:95)
at scala.tools.nsc.interpreter.ILoop.processLine(ILoop.scala:402)
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:430)
at Main$$anon.<init>(repl.scala:14)
at Main$.main(repl.scala:1)
at Main.main(repl.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.reflect.internal.util.ScalaClassLoader$$anonfun$run.apply(ScalaClassLoader.scala:70)
at scala.reflect.internal.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:31)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:101)
at scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:70)
at scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
at scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
at scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
at scala.tools.nsc.ScriptRunner.scala$tools$nsc$ScriptRunner$$runCompiled(ScriptRunner.scala:175)
at scala.tools.nsc.ScriptRunner$$anonfun$runScript.apply(ScriptRunner.scala:192)
at scala.tools.nsc.ScriptRunner$$anonfun$runScript.apply(ScriptRunner.scala:192)
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$$anonfun$apply$mcZ$sp.apply(ScriptRunner.scala:161)
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript.apply$mcZ$sp(ScriptRunner.scala:161)
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript.apply(ScriptRunner.scala:129)
at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript.apply(ScriptRunner.scala:129)
at scala.tools.nsc.util.package$.trackingThreads(package.scala:43)
at scala.tools.nsc.util.package$.waitingForThreads(package.scala:27)
at scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:128)
at scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:192)
at scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:205)
at scala.tools.nsc.MainGenericRunner.runTarget(MainGenericRunner.scala:67)
at scala.tools.nsc.MainGenericRunner.run(MainGenericRunner.scala:87)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:98)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
Abandoning crashed session.
scala>
如果我删除 repl.intp.bind("foo", "Int", foo)
部分,这就是我得到的:
$ scala repl.scala
scala> 123
null
Abandoning crashed session.
scala>
我做错了什么?有没有更简单的方法可以在程序 运行 期间进入交互式 REPL 进行调试?断点、单步执行和检查局部变量有时不会这样做。
我正在使用 Scala 2.11.5。
我不知道为什么这个评论没有魔法星号:
// start an interpreter with the given settings
def process(settings: Settings): Boolean
所以你可以:
scala> repl process s
Welcome to Scala version 2.11.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25).
Type in expressions to have them evaluated.
Type :help for more information.
scala> :quit
res0: Boolean = true
或者您可以:
package myrepl
import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.{ ILoop, SimpleReader }
object Test extends App {
val foo = 42
val repl = new ILoop {
override def printWelcome() = {
intp.bind("foo", foo)
super.printWelcome()
echo("Customized...")
}
}
val s = new Settings
s.usejavacp.value = true
repl.in = SimpleReader()
repl process s
/*
repl.createInterpreter()
repl.intp.bind("foo", "Int", foo)
repl.loop()
repl.closeInterpreter()
*/
}
和
$ scalac myrepl.scala && scala myrepl.Test
foo: Int = 42
Welcome to Scala version 2.11.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_20).
Type in expressions to have them evaluated.
Type :help for more information.
Customized...
scala> foo
res0: Int = 42
scala> :quit
此外,
s.Xnojline.value = true
//repl.in = SimpleReader()
由于 repl 崩溃错误,我将降级到 2.11.4...
Sbt 通过 overriding createInterpreter
and calling bind there 完成。
编辑:
val repl = new ILoop {
override def printWelcome() = {
//import scala.concurrent.duration._
//Await.ready(globalFuture, 10.minutes) // sorry, it's private!
super.printWelcome()
echo("Customizing...")
processLine("") // block for init to finish
intp.bind("foo", foo)
}
}
私有 globalFuture
是爆炸启动的障碍:
object Solid extends App {
val foo = 42
val repl = new ILoop {
override def printWelcome() = {
super.printWelcome()
echo("Customized...")
}
}
val s = new Settings
s.Xnojline.value = true
s.usejavacp.value = true
repl.settings = s
repl.createInterpreter()
repl.in = SimpleReader()
repl.intp.initializeSynchronous()
repl.loopPostInit()
repl.globalFuture = concurrent.Future.successful(true)
repl.intp.bind("foo", "Int", foo)
try repl.loop()
finally repl.closeInterpreter()
}
2.11 中不再支持 -Yrepl-sync
选项。