On 16/10/2011 00:08, JPH wrote:
Hi all,
I am passin a two-dimensional array to a sub and when the sub returns,
the original array has changed. Eventually I want to pass the array into
a recursive sub, so I want to find a way to circumvent this behaviour.
Notice how my global is "@a" and the sub local is "@b"
- Why is this happening
- How can I properly pass a two dimensional array to a sub, without the array
in main changing?
Ideas anyone?
Here is the minimal script to reproduce my finding:
=============
#!/usr/bin/perl
use warnings;
use strict;
sub try {
my @b = @_;
$b[ 0 ][ 1 ] = "7";
return 3;
}
my @a;
$a[ 0 ][ 1 ] = " ";
print "Before: " . $a[ 0 ][ 1 ] . "\n";
try( @a );
print "After: " . $a[ 0 ][ 1 ] . "\n";
exit;
=============
What happens:
Before:
After: 7
=============
What I would expect:
Before:
After: 0
=============
Naming your variables just a and b is a bad idea - the name should
reflect what they contain. Also it is generally better to pass arrays
and hashes to subroutines by reference, but I will work with what you
have written so far as, depending on the problem you are solving, any
changes may be irrelevant.
Your "two-dimensional array" @a is an array of array references, so
calling the subroutine as
try(@a);
in fact passes each row as a separate parameter, like this
try($row0, $row1, $row2, $row3);
and since your subroutine starts with
sub try {
my @b = @_;
:
}
you are simply copying those array references into @b, like this
my @b = ($row0, $row1, $row2, $row3);
so $a[0][1] is the same as $row0->[1] and so also $b[0][1], so by
changing one you are also changing the other. For the local array to be
independent of the one passed, you must duplicate all the rows,
replacing the first line of the subroutine with something like
sub try {
my @b;
foreach my $row (@_) {
push @b, [@$row];
}
:
}
I think it is unlikely that your design is the best solution to your
problem, but since you say nothing of your requirements I cannot suggest
anything better. Depending on the size of your arrays and the level of
recursion you may easily absorb large amounts of memory.
I hope this helps,
Rob
--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/