Search code examples
perlhashperl-data-structuresperl-hash

How to copy a nested hash


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


Solution

  • 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);