热键停止REPL?

Joh*_*ood 9 scala read-eval-print-loop

是否有热键来停止/退出Scala REPL?

示例:我使用命令从SBT启动Scala REPL console,然后像无限循环那样做一些愚蠢的事情,并希望在不关闭shell的情况下结束REPL.类似Ctrl+ C,Ctrl+ DCtrl+的东西Z(都不起作用).

更新: 使用的操作系统:Windows 7 64位.

Ctrl+ D存在SBT和REPL,但是当我处于无限循环之类时,Ctrl+ D不会退出REPL

while(true) prinln("test")
Run Code Online (Sandbox Code Playgroud)

有没有办法在不关闭shell的情况下使用热键退出无限循环?或者这是不可能的,因为REPL在循环通过之前不会对热键作出反应(当然,在这种情况下不会发生)?

0__*_*0__ 2

以下适用于 Scala 2.10.0-M6,但在 2.9.2 中,您可能可以:wrap在 REPL 功耗模式下实现类似的效果。

假设 REPL 是从 sbt via 启动的sbt console——不失一般性(否则你可以将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>"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后以下将激活半异步 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
...
Run Code Online (Sandbox Code Playgroud)