Как уже говорили другие, это задокументировано.
Насколько я понимаю, поведение псевдонимов @_
, for
, map
и grep
обеспечивает оптимизацию скорости и памяти, а также предоставляет интересные возможности для творчества. То, что происходит, по сути, вызов по ссылке в блоке конструкции. Это экономит время и память, избегая ненужного копирования данных.
use strict;
use warnings;
use List::MoreUtils qw(apply);
my @array = qw( cat dog horse kanagaroo );
foo(@array);
print join "\n", '', 'foo()', @array;
my @mapped = map { s/oo/ee/g } @array;
print join "\n", '', 'map-array', @array;
print join "\n", '', 'map-mapped', @mapped;
my @applied = apply { s/fee//g } @array;
print join "\n", '', 'apply-array', @array;
print join "\n", '', 'apply-applied', @applied;
sub foo {
$_ .= 'foo' for @_;
}
Обратите внимание на использование функции List :: MoreUtils apply
. Он работает как map
, но делает копию переменной темы, а не использует ссылку. Если вы ненавидите писать код вроде:
my @foo = map { my $f = $_; $f =~ s/foo/bar/ } @bar;
вы будете любить apply
, что превращает его в:
my @foo = apply { s/foo/bar/ } @bar;
На что следует обратить внимание: если вы передадите значения только для чтения в одну из этих конструкций, которая изменяет входные значения, вы получите ошибку «Изменение попытки чтения только для значения».
perl -e '$_++ for "o"'