2011-10-27 20 views
5

Scala'da etkileşimli bir kabuk yazmak istiyorum, okuma dizisi desteği (Ctrl-l, ok tuşları, satır düzenleme, geçmiş, vs.). Scala'da readline desteği ile etkileşimli kabuk nasıl yazılır?

Python bunu nasıl biliyorum:

# enable support for Ctrl-l, arrow keys, line editing, history, etc. 
import readline 

finished = False 
while not finished: 
    try: 
    line = raw_input('> ') 
    if line: 
     if line == 'q': 
     finished = True 
     else: 
     print line 
    except KeyboardInterrupt: 
    print 'Ctrl-c'; finished = True 
    except EOFError: 
    print 'Ctrl-d'; finished = True 

Ben tam aynı davranış ile, basit bir skala programı yazmak istiyorum.

// used to support Ctrl-l, arrow keys, line editing, history, etc. 
import scala.tools.jline 

val consoleReader = new jline.console.ConsoleReader() 
var finished = false 
while (!finished) { 
    val line = consoleReader.readLine("> ") 
    if (line == null) { 
    println("Ctrl-d") 
    finished = true 
    } else if (line.size > 0) { 
    if (line == "q") { 
     finished = true 
    } else { 
     println(line) 
    } 
    } 
} 

açık sorulardır:

  • nasıl ctrl-c işlemek için benim en yakın çözüm şimdiye kadar aşağıdaki scala nedir?
  • Python'a benzer bir şekilde istisnaları kullanmak mümkün mü?
  • bu en uygun çözümdür veya geliştirilebilir mi?
Örneğin, jline olayların bir hiyerarşi yazabilirsiniz

cevap

7

:

def console(handler: JLineEvent => Boolean) { 
    val consoleReader = new jline.console.ConsoleReader() 
    var finished = false 
    while (!finished) { 
    val line = consoleReader.readLine("> ") 
    if (line == null) { 
     finished = handler(EOF) 
    } else if (line.size == 0) { 
     finished = handler(EmptyLine) 
    } else if (line.size > 0) { 
     finished = handler(Line(line)) 
    } 
    } 
:

sealed trait JLineEvent 
case class Line(value: String) extends JLineEvent 
case object EmptyLine extends JLineEvent 
case object EOF extends JLineEvent 

Sonra parametre olarak JLineEvent bir işlevi götüren bir işlevde while döngü sarabiliriz

Son olarak uygun işlevle çağırabilirsiniz:

console { 
    case EOF => 
      println("Ctrl-d") 
      true 
    case Line(s) if s == "q" => 
      true 
    case Line(s) => 
      println(line) 
      false 
    case _ => 
      false 
} 

ctrl+C'u yakalamak için kapatma kancaları belki bir çözüm olabilir.