The special array, @_
, where all the arguments passed to a function are present, is actually an alias to the arguments passed. Hence, any change we make directly to this special array @_
will reflect in the main as well. This is clear.
#!/usr/bin/perl
use warnings;
use strict;
$\="\n";
sub func {
print \@_;
$_++ for(@_);
}
my @arr=(2..4);
print \@arr;
func(@arr);
print "@arr";
For the above program, I expected the reference of @arr
and @_
to point to the same location since it is an alias. But it is not so.
On running the above:
ARRAY(0x1b644d0)
ARRAY(0x1b644e0)
3 4 5
If they are pointing to 2 different locations, how the changes done in @_
is reflecting in @arr
?
Am I seeing something wrong? Please advice.
This might answer you question:
use warnings;
use strict;
$\="\n";
sub func {
print \@_;
$_++ for(@_);
print \$_ for @_;
}
my @arr=(2..4);
print \@arr;
func(@arr);
print "@arr";
print \$_ for @arr;
Output
ARRAY(0x17fcba0)
ARRAY(0x1824288)
SCALAR(0x17fcc48)
SCALAR(0x18196f8)
SCALAR(0x1819710)
3 4 5
SCALAR(0x17fcc48)
SCALAR(0x18196f8)
SCALAR(0x1819710)
As you see, individual arguments have the same address but the container is not the same. If you push an item to @_
in func
the @arr
will not change (so you can do shift
in funct
). So, each argument is an alias and array elements are passed as individual items. @_
contains all items passed into the subroutine. If you want to modify an array argument you need to pass it by reference.
@_
isn't aliased; its elements are.
Remember that
func(@arr);
is the same as
func($arr[0], $arr[1], ...);
because the only thing that can be passed to a sub is a list of scalars, and an array evaluates to a list of its elements in list context.
So that means
func(@arr);
is basically the same as
local @_;
alias $_[0] = $arr[0];
alias $_[1] = $arr[1];
...
&func;
Changing the elements of @_
will change elements of @arr
, but adding and removing elements of @_
won't change @arr
since they are different arrays.
>perl -E"@a=(4..6); sub { $_[0] = '!'; say @_; }->(@a); say @a;"
!56
!56
>perl -E"@a=(4..6); sub { splice(@_,0,1,'!'); say @_; }->(@a); say @a;"
!56
456
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With