如何像Perl字符串一样转义代码?

如何像Perl字符串一样转义代码?,perl,printing,heredoc,Perl,Printing,Heredoc,$i=1; 虽然($i很难说这段代码应该完成什么,但是您可能希望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 (

$i=1;
虽然($i很难说这段代码应该完成什么,但是您可能希望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"
}

这应该可以解决问题

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++;
}
$i=1;

而($i命令行选项
-MO=Deparse
显示了Perl在简化代码后如何解释代码(例如,将herdocs转换为qq{}块)

Perl已将
${px$i.name}
转换为
${$i->px.name}

在perl中,
${…}
意味着计算块内的任何内容,并将其视为一个(即变量名)或标量引用,然后取消引用以将其转换回标量。因此,perl尝试执行这些块内的任何内容,将其视为perl代码。这是因为您的heredoc,
“EOT”
类似于双引号字符串,并插入美元符号


解决方案是:转义您的美元符号(
$
->
\$
)或者使用单引号和串联而不是herdeocs。

my$format=我不知道这是什么,但它肯定不是Perl。print/EOT中的代码肯定不是,但这不是重点,我只需要将print/EOT中的内容写入标准输出;事实上,如果我删除“if”块,它运行得非常好。Doh——我忽略了一个事实,那就是这些东西在一个大的herdoc中。这些代码是加载cvs并从其数据创建groovy类的更大脚本的一部分。问题是为什么perl编译器试图在print/EOT中编译块,以及如何告诉它不要这样做。(顺便说一句,谢谢你的建议,但它不起作用)(+1)有多种类型的heredocs单引号是非插值的。另一种类型是反勾号,例如,
EOT
,它将通过shell执行字符串。
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;
}
$ 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';}
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;
}