http://qs1969.pair.com?node_id=256316

P0w3rK!d has asked for the wisdom of the Perl Monks concerning the following question:

Hello,
I built a hash as follows:
# build hash while() { ... $hshFoo{$key1}{$key2} = $strFileName; ... # key1 is a number # key2 is a sequential number }
When I attempt to reference the hash I get the following:
foreach $key (keys %hshFoo) { print " $key => $hshFoo{$key}\n"; }
Output:  
  6137 => HASH(0x1ddba60)
  2823 => HASH(0x1ddbd18)
  6598 => HASH(0x1ddbc88)
  4156 => HASH(0x1ddbd00)
Whereas "HASH(0x1ddba60)" contains:
6137 =>
    0 => file1.xml
    1 => file2.xml
    2 => file3.xml
What is the best way to reference the 2nd hash? I tried to create a temp hash of $hshFoo{$key} to loop through, but that failed. I need to be able to reference the 2nd key+value pair; in this case of the hash "HASH(0x1ddba60)". I tried this also...
foreach $key2 (keys $hshFoo{$key}) { ... } Type of arg 1 to keys must be hash (not hash element) at foo.pl line 341, near "}) " BEGIN not safe after errors--compilation aborted at foo.pl line 431.

-P0w3rK!d

Replies are listed 'Best First'.
Re: Referencing a HoH
by kilinrax (Deacon) on May 07, 2003 at 17:38 UTC
    Try dereferencing the temp hash:
    foreach $key2 (keys %{$hshFoo{$key}}) { ... }
    You also might want to have a look at Data::Dumper and perlref.
      Thank you. :) Everything I referenced showed %$hshFoo. I tried to dereference it that way and it did not work.
Re: Referencing a HoH
by Aristotle (Chancellor) on May 07, 2003 at 17:41 UTC
    That is to be expected. Your top hash contains references to hashes; you need to dereference them first. To do so you need a nested loop:
    foreach my $key (keys %hshFoo) { foreach my $subkey (keys %{$hshFoo{$key}}) { print "$key/$subkey => $hshFoo{$key}{$subkey}\n"; } }
    See perlref, perllol and perlreftut.

    Makeshifts last the longest.

      I had the right idea. I botched this when I did it. Thank you :)
Re: Referencing a HoH
by Enlil (Parson) on May 07, 2003 at 17:41 UTC
    You are so close..
    foreach $key (keys %hshFoo) { print " $key => \n"; foreach $key2 (keys %{$hshFoo{$key}}) { print " $key2 => $hshFoo{$key}{$key2}\n"; } }
    you might want to give perldsc another glance for more Data Structure Fun.

    -enlil

      What do I do here? Is something like this possible?
      foreach $key (keys %hshFoo) { %hsh2 = bless($hshFoo{$key}); foreach $key2 (keys %hsh2) { # ...do something w/ %hsh2 here } }
      It appears that %hsh2 becomes unusable if I try to put it in place of %hshFoo in the loop above. When I evaluate %hsh2 in the debugger I see FOO:HASH(0x1ddba60) versus $hshFoo=HASH(0x1ddba60). Is this a proper use of bless() in this instance?

      -P0w3rK!d

        No need to bless it... my %hsh2 = %{$hshFoo{$key}};
Re: Referencing a HoH
by artist (Parson) on May 07, 2003 at 18:00 UTC
    Here is the code which will help you to understand HOH
    use Data::Dumper; $hash{a1}{b1} = 'c1'; $hash{a1}{b2} = 'c2'; $hash{a2}{b1} = 'c3'; $hash{a2}{b3} = 'c4'; print Dumper(\%hash); foreach $key (keys %hash){ print "Key:\t$key\n"; my %subHash = %{$hash{$key}}; print "\tSubkeys:"; foreach $subkey (keys %subHash){ print "\t$subkey"; } print "\n"; }
    __END__
    $VAR1 = {
              'a2' => {
                        'b1' => 'c3',
                        'b3' => 'c4'
                      },
              'a1' => {
                        'b1' => 'c1',
                        'b2' => 'c2'
                      }
            };  
    
    Key:    a2
            Subkeys:        b1      b3
    Key:    a1
            Subkeys:        b1      b2
    
    
      Thank you. I have not written any Perl with hashes for about 6 months. I simply forgot the %. Shame on me :{
        You could also consider the now mostly disused pseudo-multi-dimensional array syntax:
        $h{$key1,$key2} = $val; while (my ($key, $val) = each %h) { my ($key1, $key2) = split /$;/, $key; print "$key1;$key2 -> $val\n"; }
Re: Referencing a HoH
by linux454 (Pilgrim) on May 07, 2003 at 19:50 UTC
    Let me recommend a great book, that will teach you everything you ever want or need to know about deep data structures in perl.

    Advanced Perl Programming
    by Sriram Srinivasan published by O'Reilly.

    I've used mine so much I'm starting to loose the cover.
    I think anyone serious about programming in perl should read this book.