edan has asked for the wisdom of the Perl Monks concerning the following question:
After spending an hour or two tracking down a bug, I re-discovered the following information, which is clearly stated in the each() docs:
There is a single iterator for each hash, shared by all each(), keys(), and values() function calls in the program; it can be reset by reading all the elements from the hash, or by evaluating keys HASH or values HASH.
OK, getting to the point, my program has a global HASH, and several places where I iterate over the elements using each(). In one of those places, the iteration is inside another loop. Now, the interesting part:
Sometimes I need to restart the outer loop from inside the each() loop.
my %hash = ( 'foo' => 1, 'bar' => 2, 'baz' => 3, ); OUTER_LOOP: foreach my $item qw(this that the_other) { print "$item:\n"; # keys %hash; # this resets the iterator while (my ($key, $value) = each %hash) { print " $key => $value\n"; if ($item eq 'that' && $key eq 'baz') { print "bailing out!\n"; next OUTER_LOOP; } } }
When I run this, I get:
this: foo => 1 baz => 3 bar => 2 that: foo => 1 baz => 3 bailing out! the_other: bar => 2
As you can see, when I bail out, the iteration has not completed, and the next call to each() gets me the next element in the HASH, rather than starting over again, which is What I Want.
The keys() docs states:
As a side effect, it resets HASH's iterator.
So.... if you uncomment that # keys %hash; line in my program, then you get the following:
this: foo => 1 baz => 3 bar => 2 that: foo => 1 baz => 3 bailing out! the_other: foo => 1 baz => 3 bar => 2
...which is More Like It.
So... my question (yes, there is a question buried down here...) is this:
Is this an idiom that I just haven't seen, whereby you put a call to keys() before your calls to each(), when you have this kind of situation? The wording of the keys() doc describing this behavior as a 'side effect' doesn't warm my heart, and leads me to believe it might be leading my down the dark road of Obfuscated Code... Is there another, well-accepted way to accomplish this? Also bear in mind that my real code doesn't resemble this contrived example, and I have calls to each() in other functions which will need the call to keys() in order to work correctly...
What say my fellow monks?
--
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: hash iteration with each
by diotalevi (Canon) on Mar 13, 2003 at 14:18 UTC | |
|
Re: hash iteration with each
by tommyw (Hermit) on Mar 13, 2003 at 15:25 UTC | |
|
(jeffa) Re: hash iteration with each
by jeffa (Bishop) on Mar 13, 2003 at 15:02 UTC | |
|
Re: hash iteration with each
by jonadab (Parson) on Mar 14, 2003 at 02:56 UTC | |
by Aristotle (Chancellor) on Mar 16, 2003 at 01:19 UTC |