I've got some code that doesn't work the way I expect, and I'd appreciate some help figuring out how to get it working the way I DO expect.
I'd like to use a subroutine to modify an input array. I figured that if I passed in a reference to the array, any changes I made to it would be reflected in the caller's version, too. But it apparently doesn't work that way.
my @test_array = qw (zero one two three);
shift_array(\@test_array);
print "POST SUBROUTINE: $test_array[0]\n";
sub shift_array {
my @array = @{(shift)};
shift @array;
print "AFTER SHIFT IN SUB: $array[0]\n";
}
This prints:
AFTER SHIFT IN SUB: one POST SUBROUTINE: zero
I expected it to print one
both times.
So my question is two-fold:
1) Why isn't it behaving the way I think it should? Does passing a reference to an array create a copy of the array?
2) How do I get the behavior I WAS expecting? How do I I get a subroutine to slide one or more elements off of the front of caller's copy of an input array?
Thanks in advance for any insight you can offer.
We can change the contents of array in the caller function (i.e. test_change()) through callee function (i.e. change) by passing the the value of array to the function (i.e. int *array). This modification can be effective in the caller function without any return statement.
Because my @array
is a new array that you assigned the dereferenced original array to. It's a copy.
Instead do this:
sub shift_array {
my $array = shift;
shift( @$array );
}
Edit: I originally said dereferencing it creates the problem but using @$array
is still dereferencing it. As @mob pointed out, assigning the variable is what creates the new array instead of updating the existing reference.
This is one of the (tiny number) of cases where Perl prototypes are useful.
#!/usr/bin/perl
use strict;
use warnings;
# Prototype forces the first argument to be a reference to an array
sub shift_array (\@) {
my $array = shift;
shift(@$array);
print "AFTER SHIFT IN SUB: @$array[0]\n";
}
my @test_array = qw (zero one two three);
shift_array(@test_array);
print "POST SUBROUTINE: $test_array[0]\n";
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