В Perl аргументы подпрограммы, хранящиеся в @_
, всегда являются псевдонимами значений на сайте вызова. Этот псевдоним сохраняется только в @_
, если вы копируете значения, это то, что вы получаете, значения.
так в этом подпункте:
sub example {
# @_ is an alias to the arguments
my ($x, $y, @rest) = @_; # $x $y and @rest contain copies of the values
my $args = \@_; # $args contains a reference to @_ which maintains aliases
}
Обратите внимание, что этот псевдоним происходит после расширения списка, поэтому, если вы передали массив в example
, массив расширяется в контексте списка, и @_
устанавливается на псевдонимы каждого элемента массива (но сам массив недоступно для example
). Если вы хотите последнее, вы передадите ссылку на массив.
Псевдоним аргументов подпрограммы - очень полезная функция, но ее следует использовать с осторожностью. Чтобы предотвратить непреднамеренное изменение внешних переменных, в Perl 6 вы должны указать, что вы хотите записываемые аргументы с псевдонимами с помощью is rw
.
Один из менее известных, но полезных приемов - использовать эту функцию псевдонимов для создания ссылок на массивы псевдонимов
my ($x, $y) = (1, 2);
my $alias = sub {\@_}->($x, $y);
$$alias[1]++; # $y is now 3
или псевдонимы:
my $slice = sub {\@_}->(@somearray[3 .. 10]);
также оказывается, что использование sub {\@_}->(LIST)
для создания массива из списка на самом деле быстрее, чем
[ LIST ]
, поскольку Perl не нужно копировать каждое значение. Конечно, недостатком (или недостатком в зависимости от вашей перспективы) является то, что значения остаются псевдонимами, поэтому вы не можете изменить их без изменения оригиналов.
Как tchrist упоминает в комментарии к другому ответу, когда вы используете любую из псевдонимов Perl для @_
, $_
, которую они вам предоставляют, также является псевдонимом исходных аргументов подпрограммы. Такие как:
sub trim {s!^\s+!!, s!\s+$!! for @_} # in place trimming of white space
Наконец, все это поведение является вложенным, поэтому при использовании @_
(или его части) в списке аргументов другой подпрограммы он также получает псевдонимы для аргументов первой подпрограммы:
sub add_1 {$_[0] += 1}
sub add_2 {
add_1(@_) for 1 .. 2;
}