shift
не является оператором lvalue.
$ perl -e'
use feature qw( say );
sub f { shift = 456; }
{ my $x = 123; f($x); say $x; }
'
Can't modify shift in scalar assignment at -e line 3, near "456;"
Execution of -e aborted due to compilation errors.
Однако значения, сдвинутые с @_
, тем не менее являются псевдонимами.
$ perl -e'
use feature qw( say );
sub f { my $p = \shift; $$p = 456; }
{ my $x = 123; f($x); say $x; }
'
456
или
$ perl -e'
use feature qw( say );
sub f { ${ \shift } = 456; }
{ my $x = 123; f($x); say $x; }
'
456
Проблема в том, что вы присвоили значение элемента массива с псевдонимом для $x
, а не для псевдонима $x
для элемента массива.Если вы хотите присвоить элементу имя @_
, вам необходимо присвоить ему псевдоним переменной.
$ perl -e'
use feature qw( say );
sub f { our $x; local *x = \shift; $x = 456; }
{ my $x = 123; f($x); say $x; }
'
456
или
$ perl -e'
use feature qw( say );
use Data::Alias qw( alias );
sub f { alias my $x = shift; $x = 456; }
{ my $x = 123; f($x); say $x; }
'
456
или
$ perl -e'
use feature qw( say refaliasing );
no warnings qw( experimental::refaliasing );
sub f { \my $x = \shift; $x = 456; }
{ my $x = 123; f($x); say $x; }
'
456
Преимущества my $x = shift
по сравнению с my $x = $_[0];
многочисленны, хотя и незначительны.
shift
легче набрать, чем $_[0]
. - Когда естьболее чем один параметр, вы можете использовать
shift
для каждого, а не вести счет. shift
поддерживает сложные и открытые списки параметров.(например, sub f { my $cb = shift; $cb->($_) for @_; }
) shift
микроскопически быстрее, чем $_[0]
(IIRC).