in reply to Infinite loop with each

each is inherently fragile since it uses an iterator you don't control. That's why I prefer using keys.

for my $key ( keys %some_hash ) { my $val = $some_hash{$key}; ... }

For example, each doesn't work with last or die.

>perl -le"%h=qw(a ! b @); for(1..2){ for$k(keys%h){ print ++$i,$k; las +t } }" 1a 2a >perl -le"%h=qw(a ! b @); for(1..2){ while($k=each%h){ print ++$i,$k; +last } }" 1a 2b <-- b???

Update: Added example.

Replies are listed 'Best First'.
Re^2: Infinite loop with each
by dragonchild (Archbishop) on Jun 05, 2008 at 13:32 UTC
    I'm going to have to disagree with you categorically.
    • You do control the each iterator. You just don't explicitly create it. It's very simple to reset the iterator, should you choose, with a void keys call. I do not consider this a hack.
    • In many Perls, lazy lists aren't fully implemented in for(keys%h). This means that large lists can grow your RAM unnecessarily.
    • When using a tied datastructure, such as from DBM::Deep, each() is strongly preferred due to the way tie implements hash iteration. TIEHASH provides FIRSTKEY and NEXTKEY($current_key). each() calls the methods each iteration and is generally nice. keys() has to call FIRSTKEY, then NEXTKEY($current_key) successively until it returns undef. This can be extremely costly.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?