我有一个简单的高阶函数来构建消息格式化程序。
use strict;
use warnings;
sub make_formatter {
my $level = shift;
return sub {
my $message = shift;
return "[$level] $message";
}
}
我从Perl这样使用它:
my $component_formatter = make_formatter('ComponentError');
print $component_formatter->('Hello') . "\n";
我想使用模板工具包模板中的make_formatter
。我尝试执行以下操作:
use Template;
use Template::Constants;
my $template = Template->new({
# DEBUG => Template::Constants::DEBUG_ALL,
VARIABLES => {
make_formatter => make_formatter,
}
});
my $template_str = "
[% my_formatter = make_formatter('MyFormatter') %]
<h1>[% my_formatter('Sample message') %]</h1>
";
$template->process(\$template_str);
此脚本的输出为:
$ perl test.pl
Use of uninitialized value $level in concatenation (.) or string at test.pl line 10.
<h1>[] MyFormatter</h1>
是否可以仅使用模板工具包语法来调用my_formatter
?不能选择默认情况下无法从模板工具包中调用外部Perl代码。
答案 0 :(得分:2)
首先请允许我指出,强烈建议在脚本的开头放置use strict; use warnings;
。
如果您针对生成$ template的代码段执行此操作,
您将收到一个Bareword "make_formatter" not allowed while "strict subs" in use
错误,这应该有助于您确定这不是一个有用的符号。
现在,如果您改为呼叫make_formatter()
,则将输出<h1>[] MyFormatter</h1>
。这是有道理的:您的函数返回了子模板,该子模板在模板中被称为“ MyFormatter”($ level为undef,就像您在没有输入的情况下调用make_formatter一样)。
正如海格兰德先生指出的那样,
my $template = Template->new({
VARIABLES => {
make_formatter => \&make_formatter,
}
});
导致我理解您想要的输出:
<h1>[MyFormatter] Sample message</h1>
\&make_formatter给您一个子例程引用,
在perl中通常可以使用以下命令进行调用:
my $ref = \&make_formatter; $ref->( 'Input' );
然后可以在模板的第一行中调用它, 返回另一个代码引用,然后在第二行中调用。
希望这会有所帮助!