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

Hi,

I want to print contents of a hash which itself is inside another hash.

This is how the code looks like-

my %Queues; $sql = "a valid sql statement"; $sth = $dbh->prepare($sql); $sth->execute(); while (my @Row = $sth->fetchrow_array()) { my %Hashes; $Hashes{QueueID} = 0; $Hashes{Queue} = $CustomQueue; $Hashes{MaxAge} = 0; $Hashes{Count} = $Row[0]; #print "Record Count = $Row[0] \n"; push (@{$Queues{Queues}}, \%Hashes); # set some things if ($QueueId == 0) { $Queues{TicketsShown} = $Row[0]; $Queues{TicketsAvail} = $Row[0]; } }
Once %Queues is populated with %Hashes vals, how do I print/access elements of %Hashes inside %Queues.

When I do following I get error-

while (my ($key,$value) = each(%Data)){ #print "$key = $value \n"; for(my ($k,$v) = each($key->{'Queues'})){ print "$k = $v \n"; } }
Any help will be greatly appreciated.

Thanks

Replies are listed 'Best First'.
Re: Accessing hash elements inside another hash
by toolic (Bishop) on Mar 11, 2009 at 14:35 UTC
    If you're just printing out contents for debug purposes, and you're not too picky about format, just use Data::Dumper
    use Data::Dumper; print Dumper(\%Queues);
Re: Accessing hash elements inside another hash
by kennethk (Abbot) on Mar 11, 2009 at 14:31 UTC

    Your desired data structure is a little unclear - you say you want a hash of hashes, but you have no clear primary key differentiating your sub-elements, implying you really want an array of hashes, and to add it that you handle the elements like a hash of array of hashes. A read through perllol might be helpful in determining which you really need. You've also constructed your for loop incorrectly.

    To access the file structure you have, your output code should likely look like (untested):

    while (my ($key_1,$value_1) = each(%Queues)){ if ($key_1 eq 'Queues') { foreach my $element (@{$value_1}) { while (my ($key_2,$value_2) = each(%{$element}) ) { print "$key_2 = $value_2 \n"; } } } else { print "$key_1 = $value_1 \n"; } }

Re: Accessing hash elements inside another hash
by JavaFan (Canon) on Mar 11, 2009 at 14:58 UTC
    Hard to answer that question. Your printing code iterates over %Data. You are populating %Queues. But you aren't putting hash(refs) as values of %Queues, but arrayrefs, which contain hashes. So you have hashes containing arrays containing hashes.

    And your printing code assumes the keys of %Data are hashes. The never ever are. Hash keys are always strings. No exceptions. (Strings can be used as hashes if you want to use symbolic references. But I advice you not to. And if you want to anyway, you're are on your own).

      Sorry, made a mistake in putting code. Actually %queues is prepared and returned by a sub routine into %Data. So the code is -
      my %Data = getQueues(); while (my ($key,$value) = each(%Data)){ #print "$key = $value \n"; for(my ($k,$v) = each($key->{'Queues'})){ print "$k = $v \n"; } }
        You're use of $key in the inner loop is incorrect. It should be:
        my %Data = getQueues(); while (my ($key,$value) = each(%Data)){ #print "$key = $value \n"; for(my ($k,$v) = each($Data{$key}->{'Queues'})){ print "$k = $v \n"; } }
        In general, accessing all key/value pairs in a HoH will look like:
        foreach my $key (keys(%HoH)){ foreach my $otherKey (keys($HoH{$key})){ my $value = $HoH{$key}{$otherKey}; my $result = &DO_SOMETHING($value); } }
Re: Accessing hash elements inside another hash
by Anonymous Monk on Mar 11, 2009 at 14:31 UTC