$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 ?
谢谢。
很难说这段代码应该完成什么,但也许您希望 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"
}
命令行选项-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。
这应该可以解决问题。
println "${"px$i.name"} / ${"px$i.empr.to"} OK"
println "px$i.name" / px$i.empr.to OK"
如您所见,$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的字符串转义的更多信息。
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;
}