モダンPerlの世界へようこそ

第43回 Text::Xslate:永続環境に特化したテンプレートエンジン

この記事を読むのに必要な時間:およそ 5.5 分

Text::Xslateのキャッシュ

Text::Xslateはもともと速度を稼ぐために大半がXS/Cで書かれていますが,いっそうの高速化のために,標準ではホームディレクトリ直下の.xslate_cacheディレクトリにキャッシュを保存するようになっています。このようにデフォルトのキャッシュディレクトリがシステムレベルで固定されているため,Xslateを使っているアプリケーションが複数ある環境では初期化時にcache_dirを適切に設定しておくのが無難です。

use FindBin;

my $tx = Text::Xslate->new(
  syntax => 'TTerse',
  module => [qw/Text::Xslate::Bridge::TT2Like/],
  cache_dir => "$FindBin::Bin/.cache",  # など
);

なお,どうせ一回こっきりしか実行しないスクリプトだからと思ってキャッシュを切ってしまうと,Xslateの実行速度は素のTTにも劣るほど遅くなります。Xslateを使う場合は(テスト目的でない限り)キャッシュを切らないようにしましょう。

Text::XslateとTTの違い

TTとTerseの違いについては,前掲のWEB+DB PRESS/gihyo.jpの記事にざっくりまとめられているほか,Text::Xslate::Syntax::TTerseやText::Xslate::Manual::FAQのPODにもいくらか記載があります。

一例として,前回取り上げたJavaScriptのエスケープの例を考えてみると,TTではインスタンス(ビュークラス)の設定はごく汎用的なものにとどめて,USEディレクティブを利用して動的にプラグインを読み込むようなことができましたが,Xslateの場合はUSEを使った動的なプラグインの読み込みは禁止されているので,XslateのインスタンスをつくるときにあらかじめJS用のフィルタを登録しなければなりません。

Text::Xslate::Manual::Cookbookにも名前があがっているkazeburoこと長野雅広氏のJavaScript::Value::Escapeを使うと,このような感じになるでしょうか。

use strict;
use warnings;
use FindBin;
use Text::Xslate;
use JavaScript::Value::Escape ();

my $tx = Text::Xslate->new(
  syntax => 'TTerse',
  module => [qw/Text::Xslate::Bridge::TT2Like/],
  cache_dir => "$FindBin::Bin/.cache",
  function => {
    js => \&JavaScript::Value::Escape::js,
  },
);

print $tx->render_string(<<'TMPL', { var => q/<foo>/ });
<script>
document.write('[% var | html | js %]');
</script>
<a onclick="alert('[% var | js %]')">alert</a>
TMPL

設定時に関数を定義する必要があるため,Xslateの設定をYAMLやJSONなどのファイル経由で読み書きするのはやや面倒になっていますが,上の例のように外部モジュールの方でエクスポートできる関数については,moduleの設定を調整することで対応する手もあります。

my $tx = Text::Xslate->new(
  syntax => 'TTerse',
  module => [
    'Text::Xslate::Bridge::TT2Like',
    'JavaScript::Value::Escape' => [qw/js/],
  ],
  cache_dir => "$FindBin::Bin/.cache",
);

また,XslateはTTと違ってデフォルトでHTML用のフィルタがかかりますが,適用順序によってはXSSを防ぎきれないため,document.writeやinnerHTMLに埋め込むときはXslateに標準で用意されているhtmlフィルタを明示的に追加するか,htmlフィルタの抜けを防ぐために登録する関数を以下のような形にしておく方法が知られています。

my $tx = Text::Xslate->new(
  syntax => 'TTerse',
  module => [qw/Text::Xslate::Bridge::TT2Like/],
  cache_dir => "$FindBin::Bin/.cache",
  function => {
    js => sub {
      JavaScript::Value::Escape::js(
        Text::Xslate::Util::escape_html(@_)
      )
    },
  },
);

Text::XslateはTTのかわりになれるのか?

Xslateは,適切に使えばTTよりもはるかに高速です。この点については,Xslateが話題になるたびに強調されていますし,テンプレートのベンチマーク結果などを見れば(いささか恣意的な部分はあるにせよ)誰しも納得できることです。

ただし,単に速さを強調するだけで使ってくれるのは,流行り物が好きな一部のユーザくらいのものです。国内ではYAPCやPerl Mongersグループのイベントに集まってくるような積極的なユーザによる導入事例もちらほら見られますが,世界的には(過去に何度か宣伝は行われているものの)いまのところほとんど関心を持たれていないといってもよいでしょう※4⁠。

その理由の一部はもちろん英語の壁にあるのでしょうが,ことテンプレートエンジンに関しては,それだけで片付けるわけにはいきません。

前回,TTがデファクトスタンダードとみなされるにいたった理由のひとつとして,宮川達彦氏らによるSledgeや,Perl.comの管理人として知られていたサイモン・カズンズ(Simon Cozens)氏のMaypoleその後を継いだゼバスティアン・リーデル(Sebastian Riedel)氏のCatalystといったウェブアプリケーションフレームワークの存在をあげました。Sledgeはもともと(現在のライブドア社の前身にあたる)オン・ザ・エッヂ社の社内フレームワークでしたし,Maypoleも実質的な開発期間は1年に満たないほどでしたから,それほど多くのユーザを獲得できたわけではありませんが,いまもなおTTがデファクトスタンダードの地位を守り続けていられるのは,15年にも及ぶ歴史や,アナグマ本のような書籍が存在しているからだけでなく,このような有名なフレームワークの開発者やユーザが(ときに看板を付け替えながらも)長年にわたってTTのサポートをしてきたからでもあります。

とりわけ近年は,いわゆるモダンPerlをビジネスと結びつけようとしてきたグループがさまざまなところで(自分たちがビジネスの道具として売り込もうとしているCatalystの標準テンプレートとしての)TTの疑問に答える努力を続けてきました。その善し悪しはまた項をあらためて検証するとして,Catalystを入れればほとんど必然的についてくるうえ,躓いたときにはCatalystのコミュニティがサポートしてくれるTTと,性能的には上らしいけれども,英語ではほとんどサポートがなく,既存のTTやCatalystとの互換性もあやしいXslateとでは,まともな勝負になるはずもありません。まして,Xslateの場合は,同じ藤吾郎氏がメンテナンスを続けているMouseと,Catalystチームが採用しているMooseという,非常にわかりやすい比較の対象もあります。彼らにしてみれば,例によって空気を読めない日本人が速いばかりの類似品を売り出そうとしているけれど,時期がくれば本家がそれ以上のものになるだろうからいちいち相手にする必要はない,というのが正直なところでしょう。

今回の記事でも,TTとの互換性が考慮されていないものについては,ほかにどれだけ見るべきところがあっても黙殺しましたが,特定の企業,地域,グループといった小さな枠組みを超えた世界への普及を目指すのであれば,性能を誇示するだけでなく,競合からの移行コストを最小限にするなどの工夫が不可欠です。Xslateの場合も,たとえばCookbookの記述をTTerseベースにしたり,既存のCatalystアプリのテンプレートをながめて,よく使われているにもかかわらずXslateではサポートされていない書き方をどう移行すればよいかまとめたりするだけでもずいぶん印象は変わるでしょうし,XslateはデフォルトでHTML用のフィルタがかかることからもわかるように基本的にはウェブに特化したテンプレートエンジンですから,ユーザが増えるかどうかは,汎用性の高いTT以上に,採用してくれるフレームワークの数や,そのユーザ数にかかっています。その意味ではXslate単体で売り込むよりは,tokuhiromこと松野徳大氏のAmon2のようにXslateを積極的に利用しているフレームワークを大々的に売り込んでいくほうが早道かもしれませんし,TT3が足踏みしている間にCatalystチームにXslateの有用性を認めさせることができれば,あとは芋づる式にユーザが増えていくことも期待できます。

もちろんこのようなビジネス的な施策はかならずしもXslateの開発陣が行わなければならないことではありません。ビジネスの道具としてであれ,それ以外の理由であれ,Xslateの普及を進め,その結果,Xslate風のテンプレートを書いたり,Xslateを拡張したりすることのできる開発者やデザイナの数を増やしたいという欲を持つ個人ないし団体が行えばよいことです。

ただ,いわゆる「モダンPerl⁠⁠,とりわけビジネスの世界におけるモダンPerlというのは,⁠TMTOWTDI(やり方はひとつではない)というPerlのモットーが選択肢の乱立につながり,初学者にはベストプラクティスが見えづらくなっている」という批判に対するひとつの回答,という側面もあります。ことウェブの世界に限ってしまえば,⁠Rubyには(ビジネスの世界で大成功した)Railsがあるけれど,Perlには……?」という問いに答えるための努力という言い方もできるでしょう。

モダンPerlの世界も一枚岩ではありませんので,この連載ではあえてその流れを無視して複数の選択肢を取り上げている部分もありますが,いずれにしてもその場の空気を無視していたずらに独自仕様を宣伝するだけでは,そんなノイズを拡散する前に「本家」の改善に協力しなさいよと言われても仕方ありません。もちろんガラパゴスと言われるのを覚悟で独自路線を行くのもひとつのやり方ではありますが,その問題点については,おそらく多くの方がケータイなどの世界を通じて承知しているはずです。

次回はテンプレートの話を少し離れて,そのようなモダンPerlの世界における政治的な話を少しまとめてみようと思います。

※4
台湾で開催されたOSDC.TWでは2010年,2011年と,作者である藤吾郎氏が(ライトニング)トークを行っていますし,先日開催されたYAPC::NA 2011でもJPAの牧大輔氏がCPAN Gems From The Far Eastというライトニングトークの中でText::Xslateを取り上げていました。

著者プロフィール

石垣憲一(いしがきけんいち)

あるときは翻訳家。あるときはPerlプログラマ。先日『カクテルホントのうんちく話』(柴田書店)を上梓。最新刊は『ガリア戦記』(平凡社ライブラリー)。

URLhttp://d.hatena.ne.jp/charsbar/