while ( ($key, $value) = each %hash ) {
print "$key => $value\n";
}
There's a lot going on here. First, each
%hash returns a key-value pair from the hash, as a
two-element list; let's say that the key is
"c" and the value is 3, so the
list is ("c", 3). That list is assigned to the
list ($key, $value), so
$key becomes "c", and
$value becomes 3.
But that list assignment is happening in the conditional expression
of the while loop, which is a scalar context.
(Specifically, it's a Boolean context, looking for a true/false
value; and a Boolean context is a particular kind of scalar context.)
The value of a list assignment in a scalar context is the number of
elements in the source list -- 2, in this case.
Since 2 is a true value, we enter the body of the
loop and print the message c => 3.
But that hardly matters, because the whole thing is being evaluated
in the conditional expression of the while loop.
The value of a list assignment in a scalar context is the number of
elements in the source list -- in this case, that's
0. Since 0 is a false value,
the while loop is done, and execution continues
with the rest of the program.
Of course, each returns the key-value pairs in a
jumbled order. (It's the same order as
keys and values would give,
incidentally; the "natural" order of the hash.) If you
need to go through the hash in order, simply sort the keys, perhaps
something like this:
foreach $key (sort keys %hash) {
$value = $hash{$key};
print "$key => $value\n";
# Or, we could have avoided the extra $value variable:
# print "$key => $hash{$key}\n";
}