我有一个简单的高阶函数来构建消息格式化程序。
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";
我想使用 Template Toolkit 模板中的 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>
是否可以仅使用 Template Toolkit 语法调用 my_formatter
?不能调用默认情况下不可从 Template Toolkit 调用的外部 Perl 代码。
最佳答案
首先请允许我指出,放置 use strict; use warnings;
强烈建议在脚本的开头。
如果您为生成 $template 的代码片段执行此操作,
您将得到 Bareword "make_formatter" not allowed while "strict subs" in use
错误,这应该可以帮助您确定这不是一个有用的符号。
现在如果您调用make_formatter()
相反,这将输出 <h1>[] MyFormatter</h1>
。这是有道理的:你的函数返回了 sub,它在你的模板中用 'MyFormatter' 调用(并且 $level 是 undef,因为你在没有输入的情况下调用了 make_formatter )。
正如 Haegland 先生所指出的,
my $template = Template->new({
VARIABLES => {
make_formatter => \&make_formatter,
}
});
导致我理解你想要的输出:
<h1>[MyFormatter] Sample message</h1>
\&make_formatter 为您提供子例程引用,
在 Perl 中通常你可以使用以下方式调用:
my $ref = \&make_formatter; $ref->( 'Input' );
然后可以在模板的第一行调用它, 返回另一个代码引用,然后在第二行中调用它。
希望这有帮助!
关于perl - 从 Template Toolkit 中的代码引用调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52032305/