2012-08-08 20 views
9

Gibt es einen Hotkey zum Stoppen/Verlassen der Scala REPL?Hotkey, um REPL zu stoppen?

Beispiel: Ich starte die Scala REPL von SBT mit dem Befehl console, dann mache etwas Dummes wie eine Endlosschleife und möchte die REPL beenden, ohne die Shell überhaupt zu schließen. So etwas wie Ctrl +C, Ctrl +D oder Ctrl +Z (die alle nicht funktionieren).

Aktualisierung: Verwendetes Betriebssystem: Windows 7 64 Bit.

Ctrl + D existiert SBT und die REPL, aber Ctrl + D nicht das REPL nicht verlässt, wenn ich in einer Endlosschleife bin wie

while(true) prinln("test") 

Gibt es eine Möglichkeit zu Verlassen Sie die Endlosschleife mit einem Hotkey, ohne die Shell zu schließen? Oder ist das nicht möglich, weil die REPL nicht auf Hotkeys reagiert, bis die Schleife durch ist (was natürlich in diesem Fall nicht passieren wird)?

+0

hm welches OS benutzen Sie? Weil ctrl + c den Trick für mich macht (unter MacOS 10.6) –

+0

starten Sie von sbt, weil Sie 'Konsole' sagen? –

+0

@MateuszDymczyk Oh, ich sehe, das scheint ein OS-spezifisches Problem zu sein. Ich benutze Windows 7 64 Bit Edition. Strg + C funktioniert nicht für mich. –

Antwort

2

Folgendes funktioniert mit Scala 2.10.0-M6, aber in 2.9.2 können Sie wahrscheinlich etwas Ähnliches erreichen, indem Sie :wrap im REPL Power-Modus verwenden.

Angenommen, die REPL von sbt über sbt console — ohne Beschränkung der Allgemeinheit gestartet wird (man sonst nur die ReplUtil Klasse auf scala Klassenpfad setzen kann). Angenommen, die folgende Klasse befindet sich im Klassenpfad, z. seine Quelle ist an 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>" 
    } 
    } 
} 

Dann folgenden wird die semi-Asynchron REPL aktivieren:

$ 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 
... 
+0

Wie kann ein Q +6 sein, während das A +0 ist? Wie auch immer, angesichts des Abbruchs von: wrap benötigt REPL ein generisches Templating mit integrierten Funktionen für "zeitgesteuert", "unterbrechbar" usw. –

0

zum Thema ist ein nützlich Umschalt + D Schlüssel Bindung zum Verlassen non Beenden von Auswertungen eines Programms innerhalb eines Eclipse-Scala-Arbeitsblatts.

Verwandte Themen