是否有热键可以停止/退出Scala REPL?
示例:我使用命令console
从SBT启动Scala REPL,然后像无限循环那样做一些愚蠢的事情,并希望在不关闭shell的情况下结束REPL。类似 Ctrl + C , Ctrl + D 或 Ctrl + Z (这些都不起作用)。
更新 使用的操作系统:Windows 7 64位。
Ctrl + D 存在SBT和REPL,但 Ctrl + D 不会退出REPL我处于无休止的循环中,如
while(true) prinln("test")
有没有办法在不关闭shell的情况下使用热键退出无限循环?或者这是不可能的,因为REPL在循环结束之前不会对热键作出反应(当然,在这种情况下不会发生这种情况)?
答案 0 :(得分:2)
以下适用于Scala 2.10.0-M6,但在2.9.2中,您可以在REPL电源模式下使用:wrap
实现类似的功能。
假设REPL是通过sbt console
从sbt开始的 - 不失一般性(否则你只需将ReplUtil
类放在scala的类路径上)。假设以下类在类路径上,例如它的来源是src/main/scala/ReplUtil.scala
:
import java.util.concurrent.{Executors, ExecutorService, TimeoutException, TimeUnit}
import concurrent._
object ReplUtil {
@volatile private var exec: ExecutorService = _
@volatile private var threads = Set.empty[ Thread ]
private def freshPool() { exec = Executors.newCachedThreadPool() }
freshPool()
private implicit def context = ExecutionContext.fromExecutorService( exec )
def panic() {
(new Thread {
override def run() {
try {
exec.shutdownNow()
exec.awaitTermination( 1, TimeUnit.SECONDS )
} finally {
val th = threads
threads = Set.empty
th.foreach( _.stop )
freshPool()
}
}
}).start()
}
def spawn[T](t: => T) = {
var futPrint = false
val fut = future {
val th = Thread.currentThread()
threads += th
val res = try { t } finally { threads -= th }
if( futPrint ) println( "<calculation done>\n" + res )
t
}
try {
Await.result( fut, util.Duration( 4, TimeUnit.SECONDS )).toString
} catch {
case e: TimeoutException =>
futPrint = true
"<ongoing calculation>"
}
}
}
然后以下将激活半异步REPL:
$ sbt console
...
Welcome to Scala version 2.10.0-M6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_33).
...
scala> import ReplUtil.panic
import ReplUtil.panic
scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
...
scala> power.intp.setExecutionWrapper("ReplUtil.spawn")
scala> 2+2
res1: Int = 4
scala> Thread.sleep(6000); 33
<ongoing calculation>
scala> <calculation done>
res2: Int = 33
scala> while(true) { Thread.sleep(2000); println( "Zzz" )}
Zzz
Zzz
<ongoing calculation>
scala> panic
scala> [error] (pool-5-thread-1) java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError
...
Caused by: java.lang.InterruptedException: sleep interrupted
...
答案 1 :(得分:0)
是一个有用的 Shift + D 键绑定,用于在eclipse scala工作表中退出程序的非终止计算。