2013-09-05 8 views
16

Bitte geben Sie ein Codebeispiel für die programmgesteuerte Erstellung eines eingebetteten Scala REPL Interpreters, der in Scala 2.10 funktioniert. (Ich habe dieses Q & A nach Stunden Kämmen verschiedenen Codefetzen verbringen einen Arbeits Dolmetscher zu bekommen)Embedded Scala REPL Interpreter Beispiel für 2.10

Antwort

22

Beispiel Repl.scala:

import scala.tools.nsc.interpreter._ 
import scala.tools.nsc.Settings 


object Repl extends App { 
    def repl = new ILoop { 
    override def loop(): Unit = { 
     intp.bind("e", "Double", 2.71828) 
     super.loop() 
    } 
    } 

    val settings = new Settings 
    settings.Yreplsync.value = true 


    //use when launching normally outside SBT 
    settings.usejavacp.value = true  

    //an alternative to 'usejavacp' setting, when launching from within SBT 
    //settings.embeddedDefaults[Repl.type] 

    repl.process(settings) 
} 

Einige Anmerkungen

  • ich die JLineReader zu zeigen, wählen (Standard) statt SimpleReader, weil es viel besser funktioniert, Pfeiltasten richtig handhaben, löschen etc. JLine fügt eine Jar-Abhängigkeit hinzu.
  • Das Beispiel zeigt, wie Werte in den repl (Variable e oben) gebunden werden.
  • Wenn ich settings.Yreplsync.value = true weglasse, hängt die REPL und ist nutzlos.
  • Aus meiner Prüfung, wenn beide usejavacp und embeddedDefaults Einstellungen miteinander kombiniert werden, ergibt sich ein Fehler

Das finde ich am einfachsten über SBT zu testen; build.sbt ein Beispiel:

name := "Repl" 

organization := "ExamplesRUs" 

scalaVersion := "2.10.2" 

libraryDependencies ++= Seq(
"org.scala-lang" % "scala-compiler" % "2.10.2", 
"org.scala-lang" % "jline" % "2.10.2" 
) 

Beispiel SBT Sitzung:

> run-main Repl 
[info] Running Repl 
Welcome to Scala version 2.10.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_37). 
Type in expressions to have them evaluated. 
Type :help for more information. 
e: Double = 2.71828 

scala> 2 * e 
res1: Double = 5.43656 

scala> 
+0

antwortete ich dieses http://stackoverflow.com/a/18418634/1296806 aber ich glaube nicht, habe ich versucht, 2.10, und ich vergesse immer, dass -Yrepl-sync Möglichkeit. Habe auch keine sbt Konsole benutzt. Vielen Dank! –

+1

Es gab auch diese Frage über verbindliche Werte und Klassenladeprogramme http://StackOverflow.com/a/18503457/1296806 Ich kann nicht sagen, ob es gute Informationen sind, weil es ignoriert wurde. Wo denkt die Masse, wenn du sie brauchst? –

+0

@ som-snytt Ja, Ihre Antwort war die einzige nützlichste Quelle für dieses Beispiel –

2

Basierend auf Bens ausgezeichnete Antwort, ist eine Hilfsklasse zu erleichtern, den Interpreter zu starten. Verbrauch:

Repl.run(("e", "Double", 2.71828), ("pi", "Double", 3.1415)) 

Es erkennt automatisch, wenn Sie von SBT laufen und aufnimmt.

Repl.scala:

import scala.tools.nsc.interpreter.ILoop 
import scala.tools.nsc.Settings 
import java.io.CharArrayWriter 
import java.io.PrintWriter 

object Repl { 

    def run(params: (String, String, Any)*) { 

    def repl = new ILoop { 
     override def loop(): Unit = { 
     params.foreach(p => intp.bind(p._1, p._2, p._3)) 
     super.loop() 
     } 
    } 

    val settings = new Settings 
    settings.Yreplsync.value = true 

    // Different settings needed when running from SBT or normally 
    if (isRunFromSBT) { 
     settings.embeddedDefaults[Repl.type] 
    } else { 
     settings.usejavacp.value = true 
    } 

    repl.process(settings) 
    } 

    def isRunFromSBT = { 
    val c = new CharArrayWriter() 
    new Exception().printStackTrace(new PrintWriter(c)) 
    c.toString().contains("at sbt.") 
    } 

}