1

我正在尝试将 perl Text::Template用于短模板,但到目前为止未能让它遍历数组。

这是我写的一个简短的测试程序来演示我正在尝试做的事情:

#!/usr/bin/perl
use Text::Template;
my $template = Text::Template->new(TYPE => 'STRING', SOURCE => <<'__EOT__');
array[0]: { $array[0] }
{ foreach my $i (@array) { }
 {$i}
}
__EOT__
print $template->fill_in(HASH => { array => [qw(item1 item2)]});

根据 Text::Template 手册,我希望这会打印: array[0]: item1 item1 item2 但它会打印 array[0]: item1

(即循环外第一行的输出和一个空行)。

我在网络上的任何地方都找不到任何人在模板中实际使用循环的示例,尽管文档说它应该“正常工作”。

我错过了什么?

4

2 回答 2

1
my $template = Text::Template->new(TYPE => 'STRING', SOURCE => <<'__EOT__',  DELIMITERS => [qw(<% %>)],);

选择不同的分隔符。出于各种原因,文档建议您多次这样做,主要是为了更容易使用,因为 Perl 代码也使用{}大括号。它还说:

由于没有反斜杠转义,模板的解析得到了简化,使用替代的 DELIMITERS 可以将解析过程加快 20-25%。这表明我最初选择的 { 和 } 非常糟糕。

只是{$i}在这里不起作用,因为它在无效的上下文中。文档说:

最后执行的语句的结果将在标量上下文中进行评估;该语句的结果是一个字符串,它被插入到模板中以代替程序片段本身。

$OUT用变量重写它:

<% foreach my $i (@array) {
    $OUT .= $i
} %>

文档说:

您附加到此变量的任何内容都将出现在模板的输出中。此外,如果您在程序片段中使用 $OUT,则将片段替换为其返回值的正常行为将被禁用;相反,片段被替换为 $OUT 的值。

<% $OUT .= $_ for @array %>

结果相同,但更短。

于 2011-05-06T07:36:11.933 回答
0

一些实验表明:

{ stuff }

变成(有效地)像这样的伪perl:

my $x = eval(stuff);
$template =~ s/{ stuff }/$x/;

所以“东西”需要是一个表达式,以便它返回一些东西来放入模板中。你的“东西”是一个foreach没有价值的循环,所以你的模板没有做任何有趣的事情。

如果您查看测试Text::Template(总是转到测试套件以获取示例,CPAN 包的测试套件对于了解事物的工作方式非常宝贵),您会看到如下内容:

{ $t = ''; foreach $n (1 .. 20) { $t .= $n . ' ' } $t }

请注意$t正在使用的方式。这表明您希望模板更像这样:

array[0]: { $array[0] }
{ $t = ''; foreach my $i (@array) { $t .= "\t$i\n" } }

还有$OUT可以代替$t上面的特殊变量。CPAN 包的文档通常非常好,非常值得一读,当您使用其他语言工作时会错过它。

于 2011-05-06T07:33:32.113 回答