S-JIS[2011-10-08] 変更履歴
ScalaのREPLでは、「:power
」コマンドを実行するとパワーユーザーモード(個人的にはパワーモードと呼んでいる)になる。
scala> :power ** Power User mode enabled - BEEP BOOP SPIZ ** ** :phase has been set to 'typer'. ** ** scala.tools.nsc._ has been imported ** ** global._ and definitions._ also imported ** ** Try :help, vals.<tab>, power.<tab> **
パワーモードでしか扱えないコマンドが増える他に、パワーモードでしか使えない変数が現れる。
この変数はREPLインタープリターが使っているインスタンスそのものだったりするので、色々なことが出来る。
コマンド・ 変数(型) |
説明 | 備考 | |
---|---|---|---|
:dump |
REPLインタープリター内部の情報を表示する。 | ||
:wrap |
REPLの式をラップして、独自処理を実行できる。 | →xuweiさんのScala2.9.0のREPLで、すごく便利な裏技を発見した件 | |
:phase |
|||
vals |
ReplVals | REPLインタープリターで使用できる変数を(たぶん)全て保持している。 | 例えばintp とvals.intp とrepl.intp は同じもの。 |
repl |
ILoop | REPLを表すオブジェクト。 コロン「 : 」で始まるコマンドはこのクラスで処理する。 |
REPLに入力されたコマンドの実行は、以下のような順のメソッド呼び出しで実行される。
|
intp |
IMain | インタープリターを表すオブジェクト。 | |
history |
History | REPLに入力したコマンドの履歴を保持するオブジェクト。 | |
global |
Global | コンパイルして出来る木構造を扱う為のオブジェクト。 | →Scalaコンパイラプラグイン |
REPL上のコマンドラインから入力されたコマンドは、ILoop#command()に渡されて解釈・実行される。
つまり、自分でrepl.command()を呼び出すと、REPLで実行したかのような結果が得られる。
scala> repl.command("val zzz = 123") zzz: Int = 123 res16: $r.repl.Result = Result(true,Some(val zzz = 123)) scala> zzz res17: Int = 123
「REPL上で独自のクラスを生成する」為の関数を作ったりすることも出来る。
scala> def defClass(name: String): Unit = { | val s = """class %s { override def toString() = "<%s>" }""".format(name, name.toLowerCase) | repl.command(s) | } defClass: (name: String)Unit scala> defClass("Zzz") defined class Zzz scala> new Zzz res22: Zzz = <zzz>
repl.command()がコマンド実行の入り口なので、これをオーバーライドしてやれば独自のREPLコマンドが定義できそう!
なのだが、repl(ILoop)はMainGenericRunner#process()の中で「new ILoop」の形で生成しているので、独自クラスに差し替える隙が無い(嘆)
repl.command()内からさらに呼ばれるintp.interpret()というメソッドがあり、repl.intpはvarなので置き換えられる。
repl.intp = new repl.ILoopInterpreter {
override def interpret(code: String) = {
println("code!" + code)
super.interpret(code)
}
}
scala> 123
code!123
res0: Int = 123
ただし、それまで保持されていた変数は受け渡されない。(resも0からに戻るし、valsやreplといった変数も使えなくなる)
変数以外にも重要なものを保持しているかもしれないので、実際に使うには不安…。
名前の通り、仮想ディレクトリー。
REPL上で定義した変数や関数は、内部でクラスを作ってコンパイルされ、仮想的なファイルシステム内にclassファイルのような形で保持している。
(と言うほど分かりやすいクラス名じゃないので使い方が分からないのだが(爆))
→仮想ディレクトリー内のファイルを実際のファイルシステムへコピー(保存)する例
REPL上で使うクラスをロードする為のクラスローダー。
REPL起動時の-cpオプションや「:cp
」コマンドによって指定されたクラスパスを含んでいる。