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