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

I'm not sure if this is a multi dimensional hash, but I'm grabbing the information from an XML document and I'm parsing it into a hash. It works fine, except when I'm trying to navigate through one of this multiple-keys:

'characters' => { 'Apple' => { 'fruit_id' => '0' }, 'Orange' => { 'fruit_id' => '0' }, }


I'm trying to loop through each key, I dont care what the data is in the element, I just want the key, I tried doing something like this:

my $fruits_xml = $xml_feed->{grocery}->{produce}; #narrowing just to produce here. while( my ($fruit_name) = each %$fruits_xml) { ... }
I generally know how a hash functions, but for some reason this results as an infinite loop, iterating through the hash over and over.

This is my first time working with hashes, and really this project is being done for learning how to be more comfortable with hashes and references.

Any ideas / tips to help me along my way?

Thanks!

Replies are listed 'Best First'.
Re: 'Multi-Dimensional' Hash
by ikegami (Patriarch) on Oct 20, 2009 at 21:55 UTC

    but for some reason this results as an infinite loop,

    This has nothing to do with multi-level hashes. Something (keys, values or each) in the loop (in ...) must be reseting the %$fruits_xml's iterator.

    my %h = qw( a 1 b 2 c 3 d 4 ); for (1..2) { my $i = 0; while (my ($key) = each %h) { print $key; keys(%h) if $_ == 2; # Reset %h's iterator in second test. last if ++$i == 10; # Break out of infinite loop. } print("\n"); }
    $ perl a.pl cabd cccccccccc
      Is this common to have to do it this way?
      I'll grab my example code when I get home again and have another look.
        The code demonstrates what you are doing wrong, so your question doesn't make sense to me.
Re: 'Multi-Dimensional' Hash
by kennethk (Abbot) on Oct 20, 2009 at 21:50 UTC
    When I run the code

    #!/usr/bin/perl use strict; use warnings; my $characters = { 'Apple' => { 'fruit_id' => '0' }, 'Orange' => { 'fruit_id' => '0' }, }; while( my ($fruit_name) = each %$characters) { print "$fruit_name\n"; }

    I get output

    Apple Orange

    which I assume is what you want. This is pretty much cut-and-paste from what you posted, so I'm not sure where your actual code has gone wrong. Perhaps your XML reader is not returning what you think? Tips include the friendly perlref, perlreftut, perllol, and perldsc.