是否有可能创建(enter) Scala REPL 中的嵌套环境,这样之后exiting嵌套环境中,在退出环境中创建的所有变量绑定都会丢失?
这就是我的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 不可能实现这一点,但您可以使用菊石 REPL http://www.lihaoyi.com/Ammonite/#Ammonite-REPL:
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._
我还没有对此进行严格测试,因此可能存在未覆盖的边缘情况,但我能够轻松地深入几个级别,然后剥离各层。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)