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?


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.