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

When I try to extract data from a hash I've created, I get wrong results. I have a script that parses a configuration file and populates some hashes with parts of the contents. Writing the hash is done like:
} elsif($gateway_cluster) { #print "adding gwc :$addr: :$fqn: :$customer_name: :$object_name: : +$fw_ver:\n"; $cluster_info{$addr} = { fqn => "$fqn", customer_name => "$customer_name", cluster_name => "$object_name", fw_ver => "$fw_ver", } #} elsif.....
Later in the script I try to retrieve the information and get weird results. After trying everything I could think of to troubleshoot, I pasted in the following section 3 times:
print "##############################################################\ +n"; if(VERBOSE) { my $counter = 1; print "The cluster_info tables:\n------------------------\n"; while ( my ($IP, $hashref) = each %cluster_info) { printf "%-3s %-20s %-18s %s", "$counter", "cluster IP:", ":$I +P:", "\n"; for my $param ( sort keys %{ $hashref } ) { printf "%-20s %-18s %s", "$param" . ":", ":$cluster_info{$ +IP}{$param}:", "\n"; } $counter++; print "=====================================================\ +n"; } }
This printed the contents of the hash three times, with an entry counter; one printing after another. The 1st time had eight entries. The 2nd and 3rd were identical with 58 entries each, of which entries 51 - 58 corresponded to the entries 1 - 8 in the 1st printing. It is as if the first time through %cluster_info is getting accessed from the 51st position instead of the 1st. Then I changed the printing loop by adding this line at the top, right after setting the counter:
print "size of hash: " . keys( %cluster_info ) . ".\n";
Then everything became correct. This problem has been reproduced using recent 5.8.x versions of ActivePerl on Windows XP and 2000, and recent ActivePerl on Solaris 8, and using the most recent Cygwin with Perl on Windows 2000. What am I doing wrong?

Replies are listed 'Best First'.
Re: Wrong hash output
by tlm (Prior) on Jul 17, 2005 at 19:30 UTC

    Put this before the first call to each %cluster_info:

    keys %cluster_info;
    and see if it helps. (Yes, that's a call to keys in a void context. Its purpose is to reset the each "iterator" associated with %cluster_info. See the discussion in this recent meditation for more on this.)

    the lowliest monk

      Thank you very much tlm, that is the answer I needed.

      As you can see from my original post, I had already figured out that using "keys" seemed to reset the iterator of %cluster_info, but I didn't know why it was off in the first place. Your pointer to the recent meditation and another look at "perldoc -f each" cleared things up for me.

      Thanks to everyone who responded for their help. This is my first time on this site and I am so grateful for the help finding a resolution before getting back to the office tomorrow morning. I think now I'd better review a lot of other code I've written for the same problem.

      -Matthew
Re: Wrong hash output
by virtualsue (Vicar) on Jul 17, 2005 at 19:40 UTC
    After you have populated this hash, try displaying its contents via Data::Dumper. Perhaps you are inadvertently creating more hash keys than you intended. That's extremely easy to do.
      Agree, and just wanted to say, when you're dumping, dump a reference to the hash and your output will be better. (Don't dump the hash itself)
      use strict; use warnings; use Data::Dumper my %hash = (a=>1) print "hash: " . Dumper( {%hash} ); # not Dumper(%hash)
      good luck!
Re: Wrong hash output
by brian_d_foy (Abbot) on Jul 17, 2005 at 19:17 UTC

    What's "weird" output? Can you show what you were expecting and what you actually got? Remember that a hash won't necessarily give you the same order of keys each time.

    --
    brian d foy <brian@stonehenge.com>
      What is weird is that after reading the configuration file into the hash, when I ennumerate the contents of the hash repeatedly I get a different number of members of the hash the first time than I do each subsequent time.

      The output for each individual member of the hash is correct, but there is a wrong number of members.