Scala - 初始化REPL环境

时间:2012-09-27 21:05:48

标签: scala embed bind read-eval-print-loop

嗨。我想将带有初始化环境的Scala REPL嵌入到我的应用程序中。我看过IMain类,看起来我可以通过它的实例来做。该实例已创建,然后存储到intp process()的{​​{1}}个公共变量中。

如何在ILoop之前绑定某些名称和/或添加一些导入(例如在REPL之前)?

以下代码在第3行失败,因为尚未创建process()(=> NPE):

intp

谢谢 - 。

更新:遗憾的是,覆盖 val x = 3 val interp = new ILoop interp.bind("x", x) // -> interp.intp.bind("x", x) val settings = new Settings settings.usejavacp.value = true interp.process(settings) 不起作用:

createInterpreter()

解释器停留在输入上(看起来像死锁,只发生在上面的代码中):

    val x = 3
    val interp = new ILoop {
        override def createInterpreter() {
            super.createInterpreter()
            intp.bind("x", x) // -> interp.intp.bind("x", x)
        }
    }
    val settings = new Settings
    settings.usejavacp.value = true
    interp.process(settings)

感谢dvigal的建议。

2 个答案:

答案 0 :(得分:4)

有一个名为scala-ssh-shell的github项目可以做你想做的事情,或者至少能让你更接近。

答案 1 :(得分:1)

-Hi,对不起我不是Scala REPL黑客,但我认为你可以做类似的事情:

class YourILoop(in0: Option[BufferedReader], protected override val out: JPrintWriter)         
    extends ILoop(in0, out) {
    override def createInterpreter() {
       if (addedClasspath != "")
          settings.classpath append addedClasspath

          intp = new ILoopInterpreter
          val x = 3;
          intp.bind("x", x)
    }
}
object Run {
    def errorFn(str: String): Boolean = {
      Console.err println str
      false
    }

    def process(args: Array[String]): Boolean = {
        val command = new GenericRunnerCommand(args.toList, (x: String) => errorFn(x))
        import command.{ settings, howToRun, thingToRun }
        new YourILoop process settings
    }
    def main(args: Array[String]) {
        process(args)  
    }
}