2006-06-30
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 %]
いいと思います。
