Problem with changes to referrenced object

R

rosenthd

Hi,

I'd like to use a copy of my "test" object below without it being
changed. However, all of my attempts so far to copy it don't seem
to succeed. As the example shows below changing newarray affects the
test object. How Can I copy values from the test array into a new
array without changing the original test array.


$test[0]{'A'} = 1;
$test[1]{'A'} = 1;
$test[2]{'A'} = 2;
$test[2]{'C'} = 3;
$test[3]{'B'} = 3;



@newarray = @test;

$testref = \@test;


for ($x=0;$x<=$#{$testref};$x++)
{
#print "$x\n";
foreach $elem (keys %{${$testref}[$x]})
{
print "$x: $elem, ${$testref}[$x]{$elem}\n";

}

}

print "Setting G to 3\n";
$newarray[0]{'G'}=3;


for ($x=0;$x<=$#{$testref};$x++)
{
#print "$x\n";
foreach $elem (keys %{${$testref}[$x]})
{
print "$x: $elem, ${$testref}[$x]{$elem}\n";

}

}

Here's my output:

0: A, 1
1: A, 1
2: A, 2
2: C, 3
3: B, 3

Setting G to 3


0: A, 1
0: G, 3
1: A, 1
2: A, 2
2: C, 3
3: B, 3
 
G

Gunnar Hjalmarsson

I'd like to use a copy of my "test" object below without it being
changed. However, all of my attempts so far to copy it don't
seem to succeed. As the example shows below changing newarray
affects the test object. How Can I copy values from the test
array into a new array without changing the original test array.

$test[0]{'A'} = 1;
$test[1]{'A'} = 1;
$test[2]{'A'} = 2;
$test[2]{'C'} = 3;
$test[3]{'B'} = 3;

@newarray = @test;

@test contains references to anonymous hashes, so @newarray is
assigned references to just those anonymous hashes.

Instead of

@newarray = @test;

you need to do something like

for my $i (0..$#test) {
for my $key ( keys %{ $test[$i] } ) {
$newarray[$i]{$key} = $test[$i]->{$key};
}
}

@newarray now contains references to _copies_ of the anonymous hashes
instead of references to the original ditto.

HTH
 
J

Jeff 'japhy' Pinyan

[posted & mailed]

I'd like to use a copy of my "test" object below without it being
changed. However, all of my attempts so far to copy it don't seem
to succeed. As the example shows below changing newarray affects the
test object. How Can I copy values from the test array into a new
array without changing the original test array.

You want to make a "deep copy", not a "shallow copy". A shallow copy only
goes one level deep, whereas a deep copy is thorough, and copies EACH
level of reference.

You might want to use the Storable module's dclone() function.

Also, I suggest reading

http://www.stonehenge.com/merlyn/UnixReview/col30.html
 
E

Eric Bohlman

(e-mail address removed) wrote in
I'd like to use a copy of my "test" object below without it being
changed. However, all of my attempts so far to copy it don't seem
to succeed. As the example shows below changing newarray affects the
test object. How Can I copy values from the test array into a new
array without changing the original test array.


$test[0]{'A'} = 1;
$test[1]{'A'} = 1;
$test[2]{'A'} = 2;
$test[2]{'C'} = 3;
$test[3]{'B'} = 3;



@newarray = @test;

@newarray will be what's known in the business as a "shallow copy" of
@test, which means that the actual array elements will be copied, but the
things they reference won't. In other words, you'll have two arrays of
references to the *same* hashes, giving you the result you experienced.

What you need is a "deep copy" or "clone" of @test. Probably the easiest
way to do it is to get the Clone::Any module from CPAN, which will provide
you with functions that make cloning nested data structures simple.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top