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!