Question

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

produces the error:

Can't call method "px" without a package or object reference at borrar.pl line 3.

How can I "escape" the if ?

Thanks.

Was it helpful?

Solution

It's kind of hard to tell what this code is supposed to accomplish, but maybe you want the outer dollar signs in the println statement to be preserved in the final output?

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

With that change, the error-free output I see is:

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"
}

OTHER TIPS

The command line option -MO=Deparse shows you how Perl has interpreted your code after simplifying it (e.g. converting heredocs to qq{} blocks). e.g.

$ 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;
}

The relevant part is:

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

Perl has converted ${px$i.name} to ${$i->px . 'name'} !

In perl, ${...} means to evaluate whatever is inside the block, and treat it as a symbolic reference (i.e. a variable name) or a scalar reference, then dereference it to turn it back into a scalar. So Perl tries to execute whatever is inside those blocks, treating their contents as Perl code. This is because your heredoc, "EOT" is like a double-quoted string, and interpolates dollar signs.

Solution is: escape your dollar signs ($ -> \$) or use single quotes and concatenation rather than heredocs.

This should fix the problem.

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

As you have seen, the $px part of the string is getting evaluated. You simply need to escape it:

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

Read more about string escaping at perldoc perlop under "Gory details of parsing quoted constructs".

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;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top