Параметр командной строки -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.