5

$i=1; while($i<3) { print << "EOT"; def px$i = new E(user) if (!px$i.hasErrors()) { println "${px$i.name} / ${px$i.empr.to} OK" }

EOT

    $i++;
}

产生错误:

在 borrar.pl 第 3 行,如果没有包或对象引用,则无法调用方法“px”。

我怎样才能“逃脱” if ?

谢谢。

4

5 回答 5

6

很难说这段代码应该完成什么,但也许您希望 println 语句中的外部美元符号保留在最终输出中?

println "\${px$i.name} / \${px$i.empr.to} OK"

通过这种更改,我看到的无错误输出是:

def px1 = new E(user) 
if (!px1.hasErrors()) {
        println "${px1.name} / ${px1.empr.to} OK"
}

def px2 = new E(user) 
if (!px2.hasErrors()) {
        println "${px2.name} / ${px2.empr.to} OK"
}
于 2010-02-24T16:18:06.947 回答
4

命令行选项-MO=Deparse向您展示 Perl 在简化代码后如何解释您的代码(例如,将 heredocs 转换为 qq{} 块)。例如

$ perl -MO=Deparse test.pl
$i = 1;
while ($i < 3) {
    print qq[    def px$i = new E(user) \n    if (!px$i.hasErrors()) {\n            println "${$i->px . 'name';} / ${$i->px . 'empr' . 'to';} OK"\n    }\n\n];
    ++$i;
}

相关部分是:

println "${$i->px . 'name';} / ${$i->px . 'empr' . 'to';}

Perl 已转换${px$i.name}${$i->px . 'name'}!

在 perl 中,${...}意味着评估块内的任何内容,并将其视为符号引用(即变量名)或标量引用,然后取消引用以将其转回标量。因此 Perl 尝试执行这些块中的任何内容,将它们的内容视为 Perl 代码。这是因为您的heredoc"EOT"就像一个双引号字符串,并且插入了美元符号。

解决方案是:转义美元符号 ( $-> \$) 或使用单引号和连接而不是 heredocs。

于 2010-02-24T16:23:33.200 回答
1

这应该可以解决问题。

println "${"px$i.name"} / ${"px$i.empr.to"} OK"
println "px$i.name" / px$i.empr.to OK"
于 2010-02-24T16:22:57.933 回答
1

如您所见,$px字符串的一部分正在被评估。你只需要逃避它:

$i=1;
while($i<3) {
    print << "EOT";
    def px$i = new E(user) 
    if (!px$i.hasErrors()) {
            println "\${px$i.name} / \${px$i.empr.to} OK"
    }

EOT

    $i++;
}

在“解析引用构造的血腥细节”下阅读有关perldoc perlop的字符串转义的更多信息。

于 2010-02-24T16:23:13.233 回答
1
my $format = << 'EOT';
def px%d = new E(user)
    if (!px%d.hasErrors()) {
            println "${px%d.name} / ${px%d.empr.to} OK"
    }
EOT

for my $i ( 1 .. 3 ) {
    printf $format, ($i) x 4;
}
于 2010-02-24T22:56:54.630 回答