TT の VMethods のせいで,たまにはまりがちなこと
VMethods の予約語のせいではまる
directory という名のハッシュが items という子項目を持っていて
$stash->{directory} = { type => 'files', items => [ 'file_a', 'file_b', 'file_c', ], };
それを列挙して表示したい場合に,
<h1>[% directory.type %]</h1> <ul> [% FOREACH item IN directory.items -%] <li>[% item.name %]</li> [% END -%] </ul>
みたいなテンプレートを書いたりします。上記のように想定済みのハッシュを与えるのなら動くのですが,
$stash->{directory} = { type => 'empty directory', # items is not defined };
のように,items を設定しないでおいてもなぜか空項目が表示されたりします。
これは items という名前の VMethod が定義されている(参照)ためです。
items なんてまぎらわしいキーをハッシュにつけるなといいたいところですが,どうしてもそのまま使いたいのであれば,item という VMethod を利用して,
<h1>[% directory.type %]</h1> <ul> [% FOREACH item IN directory.item('items') -%] <li>[% item.name %]</li> [% END -%] </ul>
のようにするとうまくいきます。
undef に対する VMethod はない
文字列がブランクであれば代わりに「(未入力)」と表示する SCALAR VMethod 「empty_msg」を定義してやったとして,
[% your_name.empty_msg %]
と書いても,your_name が stash になかったり undef だったりするときには,ブランクになってしまいます。これは,表題のとおり,VMethod は undef 値にたいして呼び出されないからです(そもそもどのタイプの VMethod を呼び出せばいいのかわからないし)。
文字列に対してとわかっているのであれば,VMethod ではなく Filter として実装すれば
[% your_name | empty_msg %]
いいと思います。