in reply to How best to replicate/copy a hash of hashes

Is {  my %TAccount = %Account; } your method to copy a Hash of Hashes ? What you copied is only the mother-hash, all the sub-hashes are still the original ones. Try this:
#!/usr/bin/perl my %hash= ( 'a' => [ 1=>2, 3=>4 ], 'b' => [ 5=>6, 7=>8 ] ); print \%hash," ", $hash{'a'}," ", $hash{'b'},"\n"; my %hash2= %hash; print \%hash2," ", $hash2{'a'}," ", $hash2{'b'},"\n"; #prints HASH(0x8daf70) ARRAY(0x8aee28) ARRAY(0x8cfc10) HASH(0x8db120) ARRAY(0x8aee28) ARRAY(0x8cfc10)

As you can see, %hash2 is at a different memory location but the entries in the hash point to the same subhashes

Replies are listed 'Best First'.
Re^2: How best to replicate/copy a hash of hashes
by flexvault (Monsignor) on Oct 04, 2010 at 19:08 UTC

    Thanks, I took you're suggestion and put the prints into the program and ran it only once and printed the \hash and 3 \keys data. The output is below. 'B:' is for before the replicate/copy and 'A:' is after. As you can see, it looks like the data has been copied to a different location. I have no idea why 'B:' says 'REF' and A: says 'SCALAR', since they are the exact same print statement only adding the T to Account to show the two different hashes.

    print "\nB:Acct: ",\%Account,"\t",\$Account{"0"},"\t",\$Account{"1" +},"\t",\$Account{"10"},"\n"; { my %TAccount = (); keys( %TAccount ) = $i; foreach my $key ( keys %{ $Account{$i} } ) { $TAccount{$key} = $Account{$i}{$key}; } print "A:TAcct1: ",\%TAccount,"\t",\$TAccount{"0"},"\t",\$TAccount{"1 +"},"\t",\$TAccount{"10"},"\n"; print "\nB:Acct: ",\%Account,"\t",\$Account{"0"},"\t",\$Account{"1" +},"\t",\$Account{"10"},"\n"; { my %TAccount = %{ $Account{"$i"} }; print "A:TAcct2: ",\%TAccount,"\t",\$TAccount{"0"},"\t",\$TAccount{"1 +"},"\t",\$TAccount{"10"},"\n";
    B:Acct:    HASH(0x300c0120)     REF(0x300e72d8)		 REF(0x3002fd8c)         REF(0x300f4c00)
    A:TAcct1:  HASH(0x300e70a4)     SCALAR(0x301413b0)      SCALAR(0x30141284)      SCALAR(0x30141344)
    
    B:Acct:    HASH(0x300c0120)     REF(0x300e72d8)		 REF(0x3002fd8c)         REF(0x300f4c00)
    A:TAcct2:  HASH(0x300e7260)     SCALAR(0x30141974)      SCALAR(0x30141848)      SCALAR(0x30141908)
    

    Thank you

    "Well done is better than well said." - Benjamin Franklin

      I was talking previously about your first method which you called "Replicate Entire". The one that was so fast. And as far as I can see not working (except if you don't mind that the copies still all access the same data in the source HoH)

      You now showed results from the third method instead where you copy a subhash. Which is basically working correct as there is no problem in copying a simple hash.

        Well, I downloaded your code, and I verified your results and I got basically the same thing. I re-ran my code and they "appeared" to be 2 separate hashes. I have never used the "Replicate Entire" method before, and don't think I know enough about it to use it in the future.

        I used the third method because that is what I would like to use, but as it stands there is not enough performance improvement to go back into the code and make the changes.

        Thank you

        "Well done is better than well said." - Benjamin Franklin

      Its actually hard for me to understand how this code prints anything sensible at all. I just added white-space and comments. Something is a bit bizarre here.

      Update: Anyway $Account{"0"} is a reference to a hash. The purpose of this is to create a new hash and "take out one level of hash key" which is a reference. $Account{$i}{$key} should be a scalar and likewise $TAccount{$key} should be a scalar - the {$i} keys are "gone". I still think something is a bit weird with the code below, but I think I grok the idea of what is supposed to happen.

      print "\nB:Acct: ",\%Account,"\t",\$Account{"0"},"\t", \$Account{"1"},"\t",\$Account{"10"},"\n"; ####### { #I'm guessing this is a typo ???? ####### my %TAccount = (); keys( %TAccount ) = $i; foreach my $key ( keys %{ $Account{$i} } ) { $TAccount{$key} = $Account{$i}{$key}; } print "A:TAcct1: ",\%TAccount,"\t",\$TAccount{"0"}, "\t",\$TAccount{"1"}, "\t",\$TAccount{"10"},"\n"; print "\nB:Acct: ",\%Account,"\t",\$Account{"0"}, "\t",\$Account{"1"}, "\t",\$Account{"10"},"\n"; { #### this does nothing!!! ##### #### except hide the previous %TAccount my %TAccount = %{ $Account{"$i"} }; print "A:TAcct2: ",\%TAccount,"\t",\$TAccount{"0"}, "\t",\$TAccount{"1"}, "\t",\$TAccount{"10"},"\n";

        Hi Marshall,

        The code was a part of an answer to a previous post, and was only the updated part of the program.

        Sorry for the confusion.

        Thank you

        "Well done is better than well said." - Benjamin Franklin