В Perl вся аргументация функций происходит через массив @_. При вызове подпрограммы все переданные параметры оказываются внутри этого массива, и исходно — это список, а не копия, то есть если вы меняете $_[0], вы модифицируете оригинал.
sub foo { my ($arg1, $arg2) = @_; $arg1 = 10; # Только локальная переменная меняется }
sub bar { my ($array_ref) = @_; push @$array_ref, 42; } my @data = (1,2,3); bar(\@data); # @data теперь (1,2,3,42)
my ($a, $b) = @_ создаются копии.Если в Perl функцию передать массив так:
myfunc(@arr), и внутри функции обратиться к$_[0], что там будет?
Верный ответ: Там будет первый элемент значения массива, а не ссылка на весь массив! Чтобы передать массив как цельный объект, используйте ссылку: myfunc(\@arr).
sub print_first { print $_[0], " "; } my @a = qw/foo bar baz/; print_first(@a); # Выведет 'foo', а не ссылку на массив print_first(\@a); # Выведет ARRAY(0x...) — ссылка на весь массив
История
update_hash(%global). Внутри изменяли $_[0]. В результате — изменялся лишь локальный срез массива аргументов, а сам глобальный хэш не подвергался модификации. Корректным решением стала передача ссылки: update_hash(\%global).История
myfunc(@arr, %opts). Оказалось, что часть ключей хэша подменялась значениями массива, причём обнаружить ошибку было непросто.История
При реализации рекурсивного обхода дерева хотели изменять внутренние элементы. В функцию передавали массивы "как есть", не ссылкой. Они создали копии, изменения никак не сказывались на внешнем контексте. Проблема устранилась заменой передач на ссылочный стиль.