Scala Repl中的嵌套环境



可以在Scala repl中创建( enter )嵌套环境,以便在退出 nested环境之后,所有可变绑定在退出环境中创建会丢失?

这是我的 wish 会话的样子:

scala> val x = 1
x: Int = 1
scala> enter // How to implement this?
// Entering nested context (type exit to exit)
scala> val x = 2
x: Int = 2
scala> val y = 3
y: Int = 3
scala> exit // How to implement this?
// Exiting nested context
scala> assert(x == 1)
scala> y
<console>:12: error: not found: value y
       y
       ^
scala> 

当前的scala repl不可能,但是您可以使用ammonite repled实现类似的东西:

Welcome to the Ammonite Repl 0.8.2
(Scala 2.12.1 Java 1.8.0_121)
@ val x = 1 
x: Int = 1
@ repl.sess.save("first")
res1_1: ammonite.repl.SessionChanged = 
@ val x = 2 
x: Int = 2
@ val y = 3 
y: Int = 3
@ repl.sess.save("second") ; repl.sess.load("first") 
res4_1: ammonite.repl.SessionChanged = 
Removed Imports: Set('y, 'res1_1, 'res1_0)
@ y 
cmd5.sc:1: not found: value y
val res5 = y
           ^
Compilation Failed
@ x 
res5: Int = 1

这些会话并非完全嵌套您描述的方式,而是易于按名称跟踪,并且可以重叠。那是在repl.sess.save("first")之后,如果您不覆盖它,您仍然可以访问原始x


又玩了一些东西后,我能够炮制一个简单的对象,该对象使用堆栈跟踪会话并加载/保存它们。可以将其放入~/.ammonite/predef.sc中以自动加载Ammonite REPL:

object SessionStack {
    case class AmmSession(id: Int = 1) {
        def name = s"session_${id}"
        def next = AmmSession(id + 1)
    }
    private var sessions = collection.mutable.Stack.empty[AmmSession]
    private var current = AmmSession()
    def enter: Unit = {
        sessions.push(current.copy())
        repl.sess.save(current.name)
        current = current.next
    }
    def exit: Unit = if(sessions.nonEmpty) {
        current = sessions.pop()
        repl.sess.load(current.name)
    } else {
        println("Nothing to exit.")
    }
}
import SessionStack._

我还没有严格测试过,因此可能有一个没有覆盖的边缘案例,但是我可以轻松地将几个层次深到层。

相关内容

  • 没有找到相关文章

最新更新