« JSRuby を CodeRepos に commit しました | メイン | 英語学習ブーム@ラボ »

jjsruby - JSRuby for Rhino (笑)

id:amachang わーい \(^o^)/ JS で書ける IRC ボットライブラリできたよー

(Rhino) たのしー \(^o^)/

というのに当てられて、タイトルですでにネタバレしているとおり、JSRuby を Rhino で試せるようにしてみました(笑)。
といっても、id:tokuhirom さんが commit してくれた repl.js をちょこっといじっただけですが(笑)。


(1) CodeRepos から JSRuby をぱしっと取ってくる。
(2) Java(5 以上?)や Rhino もいれておく
(3) jsruby の trunk の下で下記実行 ( js.jar のパスは適宜指定 )

java -cp ./js.jar org.mozilla.javascript.tools.shell.Main  tools/jjsruby.js

これで対話的に Rhino 上で javascript ruby のコードを実行できます( Rhino で Javascript が実行できるのは当たり前ですね、とほほ……)。

一番苦労したのは Rhino から標準入出力をどうやって読み書きするか(笑)。



追記:Rhino で標準入出力


せっかくなのでメモ。
Rhino では print() が組み込まれていて、標準出力に文字列を出力することが出来ますが、自動的に改行されてしまうため、改行を付けたくない文字列出力(プロンプトとか)には使えません。
また、SpiderMonkey には readline() が組み込まれていて標準入力から文字列が取れますが、Rhino にはそれっぽいのは無さそうです(見つけられなかっただけで、もしかしたらあるのか?)。

Rhino からは Java のクラスが使えるのでそっちを経由して標準入出力を取りたいところ。
java.lang.System に in と out というフィールドがあり、これらがそれぞれ stdin / stdout に対応しているのでこれを取れればOK。
でも java.lang.System.in と書くと "missing name after . operator" と怒られてしまう。正解は java.lang.System["in"] 。

というわけで jjsruby では以下のように使いました。

importPackage(java.io);
var stdin = new BufferedReader(new InputStreamReader(java.lang.System["in"]));
var stdout = new OutputStreamWriter(java.lang.System["out"]);

(中略)

stdout.write("> ");stdout.flush(); // プロンプト表示
while (line = stdin.readLine()) { // 一行入力
var nodetree = parser.parse(line)
print(ruby.exec(nodetree));
stdout.write("> ");stdout.flush();
}

stdin は readLine() が使いたかったので BufferedReader でくるんでます。
stdout は短い文字列を出力しただけだと表示されないので、すぐ flush() しています。