$i=1; в то время как ($i <3) {печать <<"EOT"; px$i определения = новый E (пользователь), если (! px$i.hasErrors ()) {println "$ {px$i.name} / $ {px$i.empr.to} хорошо"}
EOT
$i++;
}
производит ошибку:
Не может назвать метод "пкс" без ссылки пакета или ссылки на объект в borrar.pl строке 3.
Как я могу "выйти" если?
Спасибо.
Трудно сказать, что должен выполнять этот код, но, может быть, вы хотите, чтобы внешние знаки доллара в операторе println сохранялись в окончательном выводе?
println "\${px$i.name} / \${px$i.empr.to} OK"
С этим изменением вывод без ошибок I см. это:
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"
}
Как вы видели, часть строки $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 в разделе "Gory details of parsing quoted constructs".
Опция командной строки -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"
, похож на строку с двойными кавычками и интерполирует знаки доллара.
Решение: экранируйте знаки доллара ($
-> \$
) или используйте одинарные кавычки и конкатенацию, а не heredoc.
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;
}
Это должно решить проблему.
println "${"px$i.name"} / ${"px$i.empr.to"} OK"
println "px$i.name" / px$i.empr.to OK"