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.