Text::MicroTemplate 版 String::TT をどう作るか

とりあえず、現状は

my $user = 'John';
my $html = eval as_html('Hello, <?= $user ?>')
    or die $@;

という方式だけど、エラー処理をユーザーが書かなきゃいけない (しかも上のコードだと警告が見えない) のが問題*1

じゃあ String::TT みたく PadWalker を使うのか、というと、生の Perl expression を埋め込む Text::MicroTemplate では、いろいろ難しそう。書くとしたら、

sub as_html2 {
    my $template = shift;
    my $h = peek_my(1);
    local $@;
    my $html = eval(
        join ';', (
            (map { "my \$_ = \$h->{$_}" } keys %$h),
            Text::MicroTemplate->new(template => $template)->code() . '->()'
        );
    die $@ if $@;
    $html;
}

みたいな感じなんだろうけど、変数のコピーが発生して副作用の影響が変わるし、やりすぎかなぁと思った。たとえば、オンメモリでカウンタ作るとして、

my $html = as_html2('you are <?= $cnt++ ?>th visitor');

みたいなコードは意図に反する動きだ、ということになるだろう。

となると、もう普通に、stash を渡す方式にして、

my $html = as_html3('Hello, <?= $args->{user} ?>', { user => 'John'});

が無難なのかなぁ。

*1:そのうえ演算子の優先順位の問題とかもあるし