Hatena::ブログ(Diary)

Islands in the byte stream

2011-02-05

Xslate meets Scalar::Defer

Template-Toolkitだと関数呼び出しの引数がない場合、括弧を省略できます。しかし、Xslateではかならず括弧が必要であり、この点が非互換となっています。これは、テンプレート内のシンボルの型を意識したほうがテンプレートコードの読みやすいからだと考えたからです。

しかし、データ型を知らないほうがいいこともあります。たとえば、必ずしも使用するわけではないデータの生成のコストが高いとわかったとき、そのデータをあとから遅延評価したい、ということもあるでしょう。しかし、あとから変数の参照を関数の呼び出しに変更するのは大変な作業です。

このような場合、以下のようにScalar::DeferScalar::Lazyを使うことで、テンプレートを書き換えることなくパラメータの遅延評価を行えるようになります*1

#!perl -w
use 5.10.0;
use strict;
use Text::Xslate;
use Scalar::Defer;

my $tx = Text::Xslate->new();

my %vars = (
    foo => defer { 'Xslate' },
    bar => defer { [1,2,3] },
);

# no need to call it explicitly
say $tx->render_string('Hello, <: $foo :> world!', \%vars);
# => Hello, Xslate world!

# Xslate 1.0003 feature
say $tx->render_string(': for $bar -> $i { $i }');
# => 123

*1:ただし、for loopでのoverload @{}の効果はバージョン1.0003からです