Text::Xslateで未設定の変数を検出する

hirose31さんの要望により、Text::Xslate 0.2013で未設定の変数を検出できるようにしました。といってもヘルパ関数を提供しただけで、実際にはtie hashを使った簡単なラッパークラスを用意しただけですが。
未設定の変数を使ったときに「FILL ME/$name」という文字列を埋め込むには、以下のようにします。なお、この機能は重いので、デバッグ時のみに使うようにする方がいいでしょう。

#!perl -w
use strict;
use Text::Xslate;
use Text::Xslate::Util qw(hash_with_default);
my $DEBUG = 1;

my %vars;
my $vars_ref = $DEBUG
  ? hash_with_default(\%vars, sub { "FILL ME/$_[0]" })
  : \%vars;

my $tx = Text::Xslate->new();
print $tx->render_string(<<'T', $vars_ref);
Hello, <: $oops :> world!
T
# => Hello, FILL ME/oops world!
__END__

いまのところネストしたオブジェクトには対応していませんが、いずれ対応すると思います。

それにしても、Hatena Diaryに慣れすぎるとlivedoor blogはちょっと使いにくいですね!

(追記)
VMを拡張するのではなく外部ヘルパクラスにしたのは、Perlレベルでも簡単にカスタマイズできることを示すためです。
事実、HashWithDefaultの実装は以下のようにごく簡単なものです。

package Text::Xslate::HashWithDefault;
use strict;

use Tie::Hash;
our @ISA = qw(Tie::ExtraHash);

sub TIEHASH {
    my($class, $storage, $default) = @_;
    return bless [ $storage, $default ], $class;
}

sub FETCH {
    my($self, $key) = @_;
    my $value = $self->[0]{$key};
    if(defined $value) {
        return $value;
    }
    else {
        return ref($self->[1]) eq 'CODE'
            ? $self->[1]->($key)
            : $self->[1];
    }
}
1;
__END__