1

How to copy a multi level nested hash(say, %A) to another hash(say, %B)? I want to make sure that the new hash does not contain same references(pointers) as the original hash(%A).

If I change anything in the original hash (%A), it should not change anything in the new hash(%B).

I want a generic way do it. I know I can do it by reassigning by value for each level of keys(like, %{ $b{kb} } = %a;).

But, there should be a solution which would work irrespective of the number of key levels(hash of hash of hash of .... hash of hash)

PROBLEM EXAMPLE

use Data::Dumper; 
my %a=(q=>{ 
            q1=>1, 
            q2=>2, 
       }, 
        w=>2); 
my %b; 
my %c; 
%{ $b{kb} } = %a; 

print "\%b=[".Data::Dumper::Dumper (%b)."] "; 
%{ $c{kc} } = %a; # $b{kb} = \%a; 
print "\n\%c=[".Data::Dumper::Dumper (%c)."] "; 

# CHANGE THE VALUE OF KEY IN ORIGINAL HASH %a 
$a{q}{q1} = 2; # $c{kc} = \%a; 
print "\n\%b=[".Data::Dumper::Dumper (%b)."] "; 
print "\n\%c=[".Data::Dumper::Dumper (%c)."] ";

Appreciate your help

gsinha
  • 1,073
  • 2
  • 16
  • 36
  • 1
    `$b{kb} = { %a };` is a bit more readable than `%{ $b{kb} } = %a;`. Being similar-looking to `$b{kb} = \%a;` makes it easier to contrast. – ikegami Jul 17 '14 at 13:36
  • @ikegami Does curly brace(eg, `{ %a }` get the reference (address) of a variable? – gsinha Jul 17 '14 at 13:43
  • @ikegami Thanks for suggesting the improvement. Got an explanation at another [Stackoverflow question](http://stackoverflow.com/q/14911586/1443563) – gsinha Jul 17 '14 at 13:47
  • `{ LIST }` is the hash constructor. It creates an anonymous hash, assigns the result of `LIST` to it, and returns a reference to the hash. – ikegami Jul 17 '14 at 14:05

1 Answers1

3

What you want is commonly known as a "deep copy", where as the assignment operator does a "shallow copy".

use Storable qw( dclone );

my $copy = dclone($src);
ikegami
  • 322,729
  • 15
  • 228
  • 466