В то время как скалярные элементы @_
являются псевдонимом передаваемых данных, @_
сам по себе является другой переменной. Это означает, что $_[1] = "foo"
изменит $_[1]
, но push @_, "foo"
не изменит @_
. В противном случае my $self = shift
был бы Bad Thing.
Вам необходимо передать массив в качестве ссылки.
sub del {
my $array_ref = shift;
splice @$array_ref, 2, 1;
return;
}
del \@array;
Если вы абсолютно необходимо сохранить интерфейс del @array
, это один из немногих мест, где это уместно использовать прототип.
sub del(\@) {
my $array_ref = shift;
splice @$array_ref, 2, 1;
return;
}
del @array;
\@
прототип говорит Perl, чтобы передать в @array
по ссылке. Я бы порекомендовал против, делая это по двум причинам. Во-первых, у прототипов есть куча предостережений, из-за которых они не стоят проблем.
Что еще более важно, это делает неочевидным то, что del
изменит свои аргументы. Обычно пользовательские функции Perl копируют свои аргументы, поэтому вы можете посмотреть foo @array
и быть достаточно уверенными. @array
не будет изменен foo
. Это позволяет быстро скопировать код для вещей, которые будут влиять на переменную. Эталонный прототип выдает это окно. Теперь каждая функция должна быть проверена на возможную скрытую перекрестную ссылку.
s/копия/другая переменная / – ikegami