Hatena::ブログ(Diary)

Islands in the byte stream

2011-02-06

mustache.js on JE

(追記あり)

Perl製のJavaScript EngineにJEというモジュールがあります。このモジュール、そこそこよくできていて、ブラウザに依存しないようなJavaScriptライブラリならだいたい動くようです。そこで、JEでmustache.jsを動かしてみました。スクリプトは本来ローカルにインストールして読み込むべきですが、ここではすぐ実行できるようリポジトリから直接とってきています。

#!perl -w
use strict;
use Test::More;

use JE;
use JSON qw(encode_json);
use Furl;

my $script = q{https://github.com/janl/mustache.js/raw/master/mustache.js};

my $je = do {
    my $res = Furl->new(agent => $0)->get($script);
    $res->is_success or die $res->status_line;

    my $je = JE->new();
    $je->eval($res->content);
    $je;
};

# unfortunately, $je->upgrade($perl) doesn't work.
sub perl2je {
    my($je, $data) = @_;
    my $json = encode_json($data);
    return $je->eval("(function () { return $json })()");
}

sub mustache {
    my($je, $input, $vars) = @_;
    # Mustache.to_html(input, vars)
    return $je->{Mustache}->method(
        to_html => $input, perl2je($je, $var)
    )->value;
}

is mustache($je,
    "Hello, {{lang}} world!\n",
    { lang => "<Mustache>" }),
    'Hello, &lt;Mustache&gt; world!';

is mustache($je, <<'T', { items => ['foo', 'bar', 'baz'] }),
{{%IMPLICIT-ITERATOR iterator=it}}
{{#items}}
    - {{it}}
{{/items}}
T
q{    - foo
    - bar
    - baz};

done_testing;

$je->upgrade()が思い通りに動いてくれないためPerlのデータ構造を一旦JSONに変換する等のハックが必要なものの、スクリプト自体はちゃんと動いているようです。

ひどく遅いのでテストくらいでしか使えませんが、JSのライブラリをそのままつかえるのは嬉しいですね。

それにしてもmustache.jsはXslateに慣れるとだいぶ奇妙ですね。auto chomp*1が{{#items}}には効いて{{it}}には効きませんし、最後の改行も勝手に削除します。空気を読み過ぎです。

(追記)

ということで、今回の件ではこれでいいものの、JEをJavaScriptライブラリの開発に使うのはリスク覚悟で、ということでした。仮にJEの完成度が高いとしても、処理系ごとのバグやクセが完全になくなることがない以上、実際のブラウザに搭載されていない処理系でのテストに一定のコストが掛かるというのは確かにそうですね。

なお、ブラウザを使ったテストについては以下のようなエントリもあります:

*1:<: ... -:>とか[% ... -%]のように続く改行を自動的に削除する機能