in reply to Re: The anomalous each()--Part II.
in thread The anomalous each()--Part II.
Am I correct that this is what you meant by saying each in scalar context?
What I meant by scalar context is that it is more usual to see each used as
while( my( $key, $value ) = each %hash ) { ...
Which puts the call to each into a list context.
Although using each in a scalar context is a perfectly legitimate thing to do (from perlfunc):
When called in list context, returns a 2-element list consisting of the key and value for the next element of a hash, so that you can iterate over it. When called in scalar context, returns only the key for the next element in the hash.
You rarely see this use, and when I discovered this anomoly, that was where I thought the problem lay.
Also, using the hash in an rvalue resets the iterator only if it's in list context. If you change %h to scalar(%h), the loop does end after iterating through all elements.
Indeed. When I came across the problem, the code was something like this.
while( my $key = each %hash ) { ... my %reversed = reverse %h; ... }
The first thing I did to try and work out what was going on was to add the line
print "$key: ", %hash;
That showed me that each was producing the same (first) key over and over. Even when I had commented out everything in the loop (except the debug print line), it still looped forever. Hence the problem *had* to be the loop condition. Didn't it?
It took a long time to work out that the print line itself was duplicating the situation that was originally caused by using %hash as an rvalue in the line above.
All in all a rather elusive problem. I guess that the behaviour is covered by the line in the perlfunc that reads:
There is a single iterator for each hash, shared by all each, keys, and values function calls in the program;
but I'd have to say that I think that it should be clearer that this includes uses of those functions that are invoked by Perl itself, and only indirectly as a result of what the programmer is doing.
I can't help but think that Perl could localise the hash before using it internally?
|
|---|