[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]

Reply via email to