看了一下模板工具包手册中的Template::Manual::VMethods部分,我没有看到可以实现此功能的方法。将undef
赋值给变量也不起作用——之后variable.defined
仍然返回true。
看了一下模板工具包手册中的Template::Manual::VMethods部分,我没有看到可以实现此功能的方法。将undef
赋值给变量也不起作用——之后variable.defined
仍然返回true。
好的,谷歌搜索"delete variable" site:mail.template-toolkit.org/pipermail/templates/
找到了来自Felipe Gasper的问题[Templates] Can I “DELETE some_var”?,并得到了Petr Danihlik的两个答案。Petr建议:
[% SET foo = 1 %]
[% IF foo.defined %] defined1 [% END %]
[% PERL %]
delete($stash->{foo});
[% END %]
[% IF foo.defined %] defined2 [% END %]
sub render {
my ( $self, $c, $template, $args ) = @_;
# [...]
my $output; # Template rendering will end here
# Variables interpolated by TT process() are passed inside an hashref
# as copies.
my $vars = {
( ref $args eq 'HASH' ? %$args : %{ $c->stash() } ),
$self->template_vars( $c )
};
# [...]
unless ( $self->template->process( $template, $vars, \$output ) ) {
# [ ... ]
}
# [ ... ]
return $output;
}
TT的process()
函数使用$c->stash
中变量的副本进行调用,那么我们为什么需要操作$c->stash
来摆脱局部副本?也许我们不需要这样做。
此外,TT的define()
VMethod和其他方法一样,似乎是为列表构建的。当对标量调用VMethod时,标量会自动提升为单个元素列表:也许出于这个原因,IF测试总是返回true。
我对带有指向DBIx::Class::ResultSet
对象的引用的变量进行了一些测试,并且在变量测试时似乎可以正常工作:
[%- resultset_rs = undef %]
[%- IF ( resultset_rs ) %]
<h3>defined</h3>
[%- END %]
__PACKAGE__->config({
# ...
EVAL_PERL => 1
});
[% RAWPERL %]
指令,这将直接让你访问 Template::Context
对象:然后你可以删除变量,并且 .defined()
VMethod 会做正确的事情。[%- RAWPERL %]
delete $context->stash->{ 'resultset_rs' };
[%- END %]
[%- IF ( resultset_rs.defined ) %]
<h3>defined: [% resultset_rs %]<h3>
[%- ELSE %]
<h3>undefined: [% resultset_rs %]<h3>
[%- END %]
0
,在布尔上下文中为假。 - Piotr Dobrogost[% RAWPERL%]
块中放置一些代码,否则可能会防止直接访问变量哈希引用。 - Marco De Lellis[% RAWPERL %]
比[% PERL %]
更有效率:RAWPERL指令允许你编写直接集成到生成的Perl子例程文本中的Perl代码。它在编译时只被评估一次,并以缓存形式存储为编译后模板子例程的一部分。这使得RAWPERL块比PERL块更有效率。我认为你应该接受自己的答案,这是一个很好的机会去了解TT的内部结构。 - Marco De Lellis
[% var %]
而不是[% stash.var %]
。我在想你是否已经尝试过修改[% stash.var %]
。 - Marco De LellisPERL
指令,因为我使用的 TT 处理器不允许内联 Perl。 - Piotr Dobrogost