Perl Tricks – each %hash

Perl has three ways to iterate a hash:

  • keys %hash iterates keys
  • values %hash iterates values
  • each %hash iterates the pair (key, value)

Perl contains an internal iterator for such kind of iteration. So far so good, as long as you finish the iteration every time. What if you break the iteration before it finishes, and start a new iteration later? According to perl doc, the iterator is reset only when

  • end of iteration
  • keys or values is called

so the script might not work as you expect in the following pattern:

while (my ($k, $v) = each %hash) {
      # do some work
      last if ($k == $somekey || $v == $somevalue);
# sometime later
while (my ($k, $v) = each %hash) {  # iterator is not reset if the previous while not finish
         # some work

The conclusion – don’t use each if you plan to break the iteration, use keys instead.