Categories

Amateur Radio (4)
Blog (36)
Calc (10)
Cars (7)
Honda Accord Hybrid (4)
Jeep (11)
Miata (21)
Coding (6)
Gadgets (235)
Sprint Ambassador (23)
Game (16)
Jokes (10)
Link Cache (36)
Misc (140)
Personal (39)
Photography (8)
Politics (1)
Tech (256)
AWS (8)
Travel (52)
Honeymoon (16)
Work (7)
Flickr

Social Stuff
Site Info

Sponsored Links

Laurie's Entries

« MatrixStream and Movie99 | Main | Installing Perforce on Linux »

Perl: Iterating and Assigning Hash of Hashes and the Enigmatic Search

So, I was trying to do something simple.  I had a normal, everyday hash of hashes in perl.  That is, something where you have the likes:

$var{$key1}{$subkey1} = $value1;
$var{$key1}{$subkey2} = $value2;
$var{$key2}{$subkey1} = $value3;
$var{$key2}{$subkey2} = $value4;


Now, anyone can iterate over a normal hash:

foreach $key (keys %var)
{
    print "$key = $var{$key}";
}
But if these are hashes, this won't work.  You might think you just iterate over the next level of hash:

foreach $key (keys %var)

{

    print "$key = $var{$key}";
    foreach $subkey (keys $var{$key})
    {
       print "$subkey = $var{$key}{$subkey};
    }

}
#or this
foreach $key (keys %var)

{
    %subhash = $var{$key};

    print "$key = $var{$key}";

    foreach $subkey (keys %subhash)

    {

       print "$subkey = $subhash{$subkey};

    }

}



This won't even compile -- "$var{$key}" isn't a hash! (It's actually the text "HASH xxx", I think.) The key to this is simple, but finding the solution wasn't because it's not a topic on it's own.  All of you have to do is basically cast it:

foreach $key (keys %var)

{

    print "$key = $var{$key}";

    foreach $subkey (keys %{$var{$key}})

    {

       print "$subkey = $var{$key}{$subkey};

    }

}
#or this

foreach $key (keys %var)


{

    %subhash = %{$var{$key}};


    print "$key = $var{$key}";

    foreach $subkey (keys %subhash)

    {

       print "$subkey = $subhash{$subkey};

    }


}




I never did find a description of this, but I first saw it when googling at the site listed below.  I wouldn't consider this advanced, or even intermediate, really.  It was just particularly difficult to find.  And the results -- or even compile errors -- listed didn't help find a solution any faster.  So how would you search to find the answer to this?

! Aware to Perl: Access and Printing of a HASH OF HASHES

Posted by Shane on March 21, 2006 10:49 AM |

TrackBacks

TrackBack URL for this entry:
http://www.kf6nvr.net/mt/kf6nvr-tb.cgi/706

Comments

That *is* actually how you do it. You got it! See "perldoc perllol" and "perldoc perldsc" and so on. Or get a copy of Learning Perl followed by Intermediate Perl.

Hi Randal!

Thank you for the searches. Everyone should know why you would know those so well. ;)

(These provide a description of all things in the line of hash of hashes, array of hashes, hash of records and the rest of the combinations. What you get is clearly marked sections for declaration, generation, access, and printing.)

I actually do have both of those books, and about 6 other Perl books. Unfortunately, they are at home where they usually get more use than at work. I suppose I could have just borrowed one from any number of my neighbors.

Thanks for confirming that I didn't do this in some ancient, deprecated way. ;) And thanks for the comment!

-Shane

You are right... it is not that hard, it should be rather simple, but the syntax is just not intuitive (most of perl is). and it is very hard to find... it took a very specific search to find this, but it was very helpfull...

here was my google search:
perl "hash of hashes" foreach

Shane, thanks for documenting this... HoH is such a useful structure, and such a pain to work with unless you can get a list of the keys... I have been searching for 30 minutes before finding your site... thankfully I have an answer now

The standard search for this in any language would be
LanguageName dereferencing
On Google for Perl:
"perl dereferencing"
First link. :)

Post a comment

Most comments moderated. I manually approve each. This takes time. Thank you for your patience.