なんてこった…CPANモジュールをnode.jsで動かしてしまうライブラリ「node-perl」
https://github.com/tokuhirom/node-perl/
ここ最近、プログラミング言語同士の壁が徐々に破壊されている気がします。あるプログラミング言語上で別なプログラミング言語を動くようにしたり、置き換えてしまったりするような類です。今回はその一つ、CPAN moduleをnode.js上で動かすという、かなり無茶な気がしなくもない、そんなソフトウェアnode-perlを紹介します。
var Perl = require('../index.js').Perl; var perl = new Perl(); perl.use('LWP::UserAgent'); var ua = perl.getClass('LWP::UserAgent').new(); var res = ua.get('http://mixi.jp/'); console.log(res.as_string());
ソースコードです。
node-perl は C++ 製、MIT Licenseのオープンソース・ソフトウェアです。
なぜつくったか
CPAN モジュールにあるのわかってるものをわざわざ porting するの、いいんですけどたいがいめんどくさいので、やらないですむぶんについてはやらないですませたかった。
CPAN モジュールをつかえばすぐできることを、まわりみちしてやりたくない。
たとえば FizzBuzz をかくのにわざわざ Acme::FizzBuzz をつくりなおさないで以下のようにすませられる。最高じゃないですか。
var Perl = require('perl').Perl; (new Perl()).use('Acme::FizzBuzz');
なんにせよ憎むべきは非中心的関心事に時間をとられることなのですから。
先行研究について
http://d.hatena.ne.jp/hide_o_55/20110222/1298383928
https://github.com/hideo55/node-perl
同名のモジュールを hide_o_55 さんがだしていたのですが、npm に publish されておらず、そうされる予定もなさそうなので、perl というネームスペースはいただきました。hide_o_55 さんの node-perl のコードも参考にさせていただいております(とはいえいじってるうちに跡形もないけど。。)。
thanks!!
ちなみに hide_o_55 さんのコードは、stdio 経由でどやこやするモジュールなので、ちょっとできることがちがいます。
むずかしかった点について
プロパティアクセスをフックしてメソッドオブジェクトをかえしてるのが、参考コードがなくてちょっと面倒だったかな。このおかげですごい楽につかえるようになってます。
SvTYPE まわりの処理もたいがい面倒なのだけど、このへんは msgpack を参考にしたので楽でした。
全般的に情報がすくないけど、node がでる前にくらべるとググればそれなりに情報えられるのでいいね。
あと、instanceof のとりかたがわからなかったけど HasInstance でした。
注意点
node-waf --perl=/usr/bin/perl configure build
という風にやると任意の perl で実行できます。ithreads 有効じゃないとうごかない気がするので、ithreads 有効な Perl をつかうといいです。
環境依存があるけど mod_perl とおなじぐらい簡単にビルドできるはずです。
pmconnect について
http://d.hatena.ne.jp/ysano2005/20060805/1154760428
Perl と js の世界をつなぐ実験としては pmconnect が有名ですね。Shibuya.pm でも発表されてましたし。今回の実装は pmconnect と同等の機能は実装されているし、それ以上にクールにつかえるようにつくったつもりですが pmconnect 自体がどっかいったのでよくわかりません。
これ blocking しますよね?
はい。します。
v8 をブロッキングでつかうけど v8 を自前でビルドしたくないからという理由で node.js をつかってるというのが僕の一貫した姿勢です。
Node.js だからブロッキングでコードをかいてはいけないというわけではありませんね。
なんで今さら node-waf なんですか?
gyp でコマンド実行してオプションとる方法がよくわからなかったかです。Patches welcome です。
node-gyp でかきなおしました。