I know the subroutine in perl pass arg by reference. But in the below code, the foreach loop in the subroutine should not be changing the value for @list
because the my $i
should be creating a new lexically scope var $i
. Any assignment to $i
should be lexically scope but not changing the @list
value.
Can anyone explain what is happening inside the foreach loop that causes the value change to @list
?
sub absList {
foreach my $i (@_) {
$i = abs($i);
}
}
@list = (-2,2,4,-4);
absList(@list);
print "@list";
Outputs:
2 2 4 4
$i
is aliased to elements of @_
array due foreach
feature (and @_
elements are aliased to elements of the @list
due @_
magic).
From perldoc
If any element of LIST is an lvalue, you can modify it by modifying VAR inside the loop. Conversely, if any element of LIST is NOT an lvalue, any attempt to modify that element will fail. In other words, the foreach loop index variable is an implicit alias for each item in the list that you're looping over.
If you want to avoid such behavior, don't iterate directly over @_
array, ie.
sub absList {
my @arr = @_;
foreach my $i (@arr) {
$i = abs($i);
}
}
$i
here refers the list elements which it gets from @_
, that's why changing $i
causes change in respective list element.
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