Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Hash of hashes assignment

by Anonymous Monk
on Apr 12, 2013 at 14:53 UTC ( [id://1028388]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, Please can someone explain to me the difference between the following two statements. It would be much appreciated. Thanks
$hashOfHashes{ $value } = { %hash }; $hashOfHashes{ $value } = %hash;

Replies are listed 'Best First'.
Re: Hash of hashes assignment
by kennethk (Abbot) on Apr 12, 2013 at 15:01 UTC
    In the first statement, you are creating an anonymous hash reference, storing in it the contents of the hash %hash via list assignment, and then storing that reference in %hashOfHashes with key value $value.

    In the second, you have a scalar assignment of %hash to %hashOfHashes with key value $value. In scalar context, a hash returns information about how many buckets are available and filled. If you have a hash with 4 key-value pairs, you might get 4/8 returned -- 8 buckets allocated with 4 filled.

    The third permutation here, and maybe what you want, would be $hashOfHashes{ $value } = \%hash; This stores a reference to %hash in %hashOfHashes with key value $value.

    For more info, see perldsc. Also relevant: perldata, perlref, perlreftut, perllol...


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      Thanks you so much. This is why I love the Perl community! Perfect explaination, thanks. I would normally use a hashref myself I was trying to figure out what this code was doing.
Re: Hash of hashes assignment
by choroba (Cardinal) on Apr 12, 2013 at 15:03 UTC
    Use Data::Dumper to visualize complex data structures.
    use strict; use warnings; use Data::Dumper; my %hash = ( Sun => 'day', Moon => 'night', ); my %hoh; $hoh{correct} = { %hash }; $hoh{wrong} = %hash; print Dumper \%hoh;

    Output:

    $VAR1 = { 'correct' => { 'Moon' => 'night', 'Sun' => 'day' }, 'wrong' => '2/8' };
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Thanks also. I had used Data:Dumper and was confused when I saw 2/8.

        The "2/8" of a hash in scalar context is just a representation of the number of "buckets" used/assigned for the hash. Note that more than one key can be assigned to the same "bucket" depending on how the hashing algorith works on the keys involved and that keys can be redistributed when more "buckets" are assigned as the hash grows.

        $ perl -Mstrict -Mwarnings -E ' > my %hash; > say scalar %hash; > for ( q{a} .. q{z} ) > { > $hash{ $_ } = 1; > say qq{$_ - @{ [ scalar %hash ] }}; > }' 0 a - 1/8 b - 2/8 c - 3/8 d - 4/8 e - 5/8 f - 6/8 g - 6/8 h - 7/16 i - 8/16 j - 9/16 k - 9/16 l - 10/16 m - 10/16 n - 11/16 o - 11/16 p - 14/32 q - 14/32 r - 14/32 s - 15/32 t - 15/32 u - 16/32 v - 16/32 w - 17/32 x - 17/32 y - 18/32 z - 19/32 $

        I hope this is helpful.

        Cheers,

        JohnGG

Re: Hash of hashes assignment
by LanX (Saint) on Apr 12, 2013 at 16:00 UTC
    IMHO, in 99% of all cases getting scalar %hash is just a bug.

    Wondering if this should produce a warning...

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: Hash of hashes assignment
by TJPride (Pilgrim) on Apr 13, 2013 at 06:40 UTC
    Try this instead of the first statement, it makes a little more sense:

    $hashOfHashes{$key} = \%hash;

    In other words, assign a reference to %hash to the key value of $key in %hashOfHashes. Using { } instead of \ does the same thing, but it is not what I would call intuitive, plus it uses one more character - a cardinal sin if you are coding in Perl.

      Using { } instead of \ does the same thing

      Not exactly. Consider:

      #! perl use strict; use warnings; use Data::Dumper; my %hash = ( Fred => 'Wilma', Barney => 'Betty' ); my $ref = \%hash; my $copy = { %hash }; $hash{Homer} = 'Marge'; # Alter the original hash print "\nReference: ", Dumper($ref); print "\nCopy: ", Dumper($copy);

      Output:

      0:10 >perl 606_SoPW.pl Reference: $VAR1 = { 'Homer' => 'Marge', 'Barney' => 'Betty', 'Fred' => 'Wilma' }; Copy: $VAR1 = { 'Barney' => 'Betty', 'Fred' => 'Wilma' }; 0:10 >

      A backslash \ produces a reference to the same hash, but braces { } create a reference to a new, separate, anonymous hash containing a copy of the data in the original.

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1028388]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2024-04-19 08:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found