[EMAIL PROTECTED] wrote:
> I am trying to make a deep copy in a complex data structure. I have a hash that has
> all of its values as anonymous arrays. I need
> to copy the entire hash as a completely separate hash so that I can manipulate the
> data in the copy without affecting the
> original data. Copying the key of the hash is easy, that is plain data. However
> copying the value is harder because it is the
> anonymous array (so whenever I try to copy the data, it always copies the reference
> to the array).
>
> -----------------------------------------
> my $hashref;
>
> sub hashref()
> {
> return $hashref;
> }
>
> $hashref->{ele1} = ["val1", "val2"];
> $hashref->{ele2} = ["val3", "val4"];
> $hashref->{ele3} = ["val5", "val6"];
>
> my %newhash = %$hashref;
>
> my @keys = keys(%newhash);
> foreach my $arraykey (@keys)
> {
> my $ref = $hashref->{$arraykey};
> $newhash{$arraykey} = @$ref;
> }
> ---------------------------------------------------
>
> But then when I do:
>
> --------------------------------------------------
> $newhash{ele1}->[0]="x";
> $newhash{ele2}->[0]="y";
>
> print $hashref->{ele1}->[0];
> print $hashref->{ele2}->[0];
> ------------------------------------------------
>
> It changes the values in both the referenced hash and the copied hash. How do I get
> a real copy?
Hi Brian.
You need to recurse down the structure and copy
each 'thing' according to whether it's a simple
value or a hash or array reference. The code below
will work, but it's by no means foolproof - there
can be references to a lot of things other than
hashes or arrays!
HTH,
Rob
use strict;
use warnings;
my $hashref;
$hashref->{ele1} = ['val1', 'val2'];
$hashref->{ele2} = ['val3', 'val4'];
$hashref->{ele3} = ['val5', 'val6'];
my $newhash = deep_copy($hashref);
$newhash->{ele1}[0] = 'x';
$newhash->{ele2}[0] = 'y';
print $hashref->{ele1}[0], "\n";
print $hashref->{ele2}[0], "\n";
print $newhash->{ele1}[0], "\n";
print $newhash->{ele2}[0], "\n";
sub deep_copy {
my $val = shift;
my $ref = ref $val;
my $copy;
if ($ref eq 'HASH') {
my ($k, $v);
$copy->{$k} = deep_copy($v) while ($k, $v) = each %$val;
}
elsif ($ref eq 'ARRAY') {
my $i = 0;
$copy->[$i++] = deep_copy($_) foreach @$val;
}
else {
$copy = $val;
}
return $copy;
}
OUTPUT
val1
val3
x
y
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]