【问题标题】:"for" loop inside a Text::Template templateText::Template 模板内的“for”循环
【发布时间】:2013-01-20 00:21:33
【问题描述】:

我正在尝试将 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 手册,我希望这样打印: 数组 [0]:项目 1 项目1 项目2 但相反,它打印 数组[0]: item1

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

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

我错过了什么?

【问题讨论】:

    标签: perl templates texttemplate


    【解决方案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 %>
    

    结果相同,但更短。

    【讨论】:

    • 感谢两位的回答。我已经知道 $OUT 和不同分隔符的选项,但问题是这不仅仅是我想在循环中重复的单个“$i”。我实际上想将它插入大约 5 行文本和可能更多的变量中。这部分模板实际上应该是: server {$server_ip} { address = {$server_ip} active = 1 weight = {$weight} }(它是lvs.cf 的一部分)。将所有这些行放在一个 "$OUT .=" 中有点违背了模板的目的。 (待续……)
    • (..继续)。尝试使用不同的分隔符时出现以下错误:数组 [0]:item1 程序片段传递错误Missing right curly or square bracket at template line 2, at end of line syntax error at template line 2, at EOF'' Program fragment delivered error 模板第 4 行不匹配的右大括号,模板第 4 行的行尾语法错误,靠近 "; #line 4 template }"'' 所以看起来它不允许我按照手册中的预期将“for”主体分解为多个 fregmants。
    【解决方案2】:

    一些实验表明:

    { stuff }
    

    被(有效地)变成了类似这种伪 perl 的东西:

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

    所以“stuff”需要是一个表达式,以便它返回一些东西以放入模板中。你的“东西”是一个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 包的文档一般都很好,值得一读,当您使用其他语言工作时会错过它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-09
      • 2012-07-25
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 2021-04-09
      • 2012-01-24
      • 2017-08-06
      相关资源
      最近更新 更多