JSXでコンパイルしたJavascriptをmongo shellで動かしてみるテスト
確実にメリットは全くないんですが何を血迷ったか、JSX でコンパイルした javascript を mongo shell に食わせて実行してみようかとふと思いついたのでやってみました。mongo shell は SpiderMonkey を使っているので、javascript が普通に動きますとのことなので、まずは試してみました。
$ mongo
> console.log("hello")
Tue Feb 12 02:20:25 ReferenceError: console is not defined (shell):1
動きませんでした。。。print()
関数しかないそうなので、とりあえずこういう逃げ。
> var console = { log : function (args) { print(args); } };
> console.log("hello")
hello
さて、JSX 側でコンパイルした際にも、これをグローバルに定義してあげないとconsole.log()
がエラーになります。あと、--executable
で実行形式で出力したときにコマンドライン引数を処理してくれるんですが、どうも mongo shell はコマンドライン引数を普通に受け取る手段がなさそうなので、ここもこけます。というわけで、fork して branch 作りました。あとついでに shebang も変えてみた。
mongo shell の中で使えるオブジェクト(用語合ってない気がします)とかを JSX から扱うには一工夫必要らしいです。ちょっとここで時間切れになったので、とりあえずrs
というレプリカセットを扱うオブジェクトに触ってみました。
import "js.jsx";
native final __fake__ class ReplicaSet {
function status() : Message;
}
class Message {
var errmsg : string;
}
class _Main {
static function main (args : string[]) : void {
var rs = js.global["rs"] as __noconvert__ ReplicaSet;
log rs.status().errmsg;
}
}
ソースはこちら。これをコンパイルして実行。
$ ./bin/jsx --executable mongo --output mongo.js example/mongo.jsx
$ chmod +x ./mongo.js
$ ./mongo.js
MongoDB shell version: 2.2.2
connecting to: test
not running with --replSet
とりあえず触れた様です。ちなみに普通に mongo shell で触るとこんな感じ。なのでちゃんとerrmsg
が取れてるみたいです。
> rs.status()
{ "errmsg" : "not running with --replSet", "ok" : 0 }
まとめ
json 形式で帰ってきたり、メソッドミッシング的な感じで collection に触れたりする、mongo shell のいいところが 全て 潰されているので実用性はゼロですが、まぁお勉強ということで。
ちなみに JSX 触ったのは今回が初めて(というか javascript すらほとんどやってない><)でしたが、先の対応のために JSX コンパイラ自体をちょっと読むことになりました。実は先日 JSX はセルフホスティングになったのでこれがなんと JSX で書かれてるんですね!なのでコンパイラを読むだけで勉強できて素晴らしかったです。
最近 Java を触り始めたので、割とすんなり JSX に入っていけました。javascript はカオスすぎて僕には手に追えません!
Enjoy!