В foreach $var (@list)
конструкции, $var
становится дискретным к элементам цикла, в том смысле, что адрес памяти $var
будет тот же адрес, что и элемент @list
. Таким образом, ваш примерный код пытается изменить значения только для чтения, и вы получите сообщение об ошибке.
Этот небольшой скрипт покажет, что происходит в foreach
конструкции:
my @a = (0,1,2);
print "Before: @a\n";
foreach my $var (@a) {
$var += 2;
}
print "After: @a\n";
Before: 0 1 2
After: 2 3 4
Дополнительная информация:This item от perlsyn
легко замазать, но дает целый совок:
Контурные петли
...
Если какой-либо элемент LIST является lvalue, вы можете изменить его, изменив VAR внутри цикла. И наоборот, если какой-либо элемент LIST не является значением lval, любая попытка изменить этот элемент приведет к ошибке . Другими словами, переменная индекса foreach является неявным псевдонимом для каждого элемента в списке, который вы зацикливаете.
Почему вы * хотите * изменить переменная цикла? Это звучит как способ сделать поведение цикла непредсказуемым. * Но возможно, это то, что вы хотите? * – pavium
Это не делает поведение цикла непредсказуемым в том смысле, что оно не мешает итератору. Результат может быть неожиданным, но он вполне предсказуем. –
+1 для любопытства и желания понять сообщения об ошибках, даже если вы уже нашли обходное решение :-). – sleske