В принципе, и практически на любом языке вы хотите передавать объекты, которые ссылаются на структуры данных, в вызывающей программе, указателях или ссылках. В Perl это будет ссылка - и вы это делаете.
Но затем в подпрограмме вы создаете локальные копии; $one
, @list
и %hash
в подпункте являются лексическими переменными
локально для sub sub , маскируя / скрывая те, что в вызывающей области. Изменения в тех, которые не делают ничего вне области действия суб.
Вместо этого напрямую используйте переданные вами ссылки для записи данных вызывающего абонента.
sub foo {
my ($rscalar, $rary, $rhash) = @_;
$$rscalar = 2;
@$rary = (4,5,6);
$rhash->{'key'} = 'valueModified';
}
foo(\$one, \@list, \%hash);
Теперь $one
, @list
и %hash
в вызывающем коде изменены. Подробнее о работе со ссылками см. Учебник perlreftut и справку perlref .
Обратите внимание, что foo(\@allLocalArgs);
передает ссылку на массив с аргументами, поэтому подпрограмма получает один элемент - ссылку на этот массив. Вы можете сделать это, но по вопросу вопроса это не нужно, поэтому я удалил его и передал список аргументов напрямую.
Еще одна вещь, на которую следует обратить внимание, это то, что аргументы имеют псевдонимы в @_
- поэтому, если в подпрограмме вы работаете с @_
напрямую, вы меняете данные в вызывающей стороне. Таким образом, если вы передадите скалярную переменную как foo($one)
, тогда $_[0] = 2
в подстановке изменится $one
в вызывающей стороне. Это в принципе лучше всего избегать, по моему мнению; если данные вызывающего абонента должны быть изменены, это должно быть сделано как можно более явным; передать ссылку.
Примечание по терминологии
A list в Perl - неуловимая, эфемерная структура, используемая для перемещения данных в программе; Подумайте о куче скаляров (значений) в стеке, которые собираются использовать, и они исчезнут. Возможно, передать аргументы функции (foo($v1, $v2)
), или сформировать строку (join '', $v1, $v2
), или создать анонимную ссылку на массив ([$v1, $v2]
) и т. Д.
Массив , с другой стороны, является многозначной переменной . Как хеш (ассоциативный массив) является многозначной переменной, в отличие от скаляра , являющегося однозначной переменной.
Много было написано об этом; Вот несколько ссылок, которые можно легко найти: Эффективная статья Perler (со ссылками на несколько других статей) и страница Stackoverflow Массив Perl против списка .
Короче говоря, вы спрашиваете о "скаляре, массиве, хэше".