I know variants of the following bug have been discussed in the Monastery recently, but I didn't find this particular one. My apologies in advance if I missed it.
Spot the bug:
sub foo { my $hashref = shift; while ( my ( $key, $value ) = each %$hashref ) { return if sometest( $key ); frobnicate( $key, $value ); } }
BTW, there's nothing arcane about this bug. It's vanilla Perl, but it's easy to miss.
This is yet another guise of the ol' each bug. The problem is that if the function is called with the same arguments twice, and if during the first call the while is exited due to the result of sometest , then in the second call to the foo, the iteration will not begin in the same place as it did in the first call. Conceivably this could be the desired behavior, but I bet that in most cases it isn't.
To fix it, use keys before the loop:
sub foo { my $hashref = shift; keys %$hashref; while ( my ( $key, $value ) = each %$hashref ) { return if sometest( $key ); frobnicate( $key, $value ); } }
Update: The original title of this thread ("Buglet") was confusing, so, by popular demand, I changed it. I hope the new title is an improvement.
the lowliest monk
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Spot the bug
by merlyn (Sage) on Dec 21, 2005 at 01:54 UTC | |
by tlm (Prior) on Dec 21, 2005 at 04:26 UTC | |
by Perl Mouse (Chaplain) on Dec 21, 2005 at 10:46 UTC | |
by demerphq (Chancellor) on Dec 21, 2005 at 14:32 UTC | |
by Perl Mouse (Chaplain) on Dec 21, 2005 at 16:29 UTC | |
by tlm (Prior) on Dec 21, 2005 at 16:51 UTC | |
| |
by merlyn (Sage) on Dec 21, 2005 at 17:04 UTC | |
by Perl Mouse (Chaplain) on Dec 21, 2005 at 17:49 UTC | |
|
Re: Spot the bug
by ysth (Canon) on Dec 21, 2005 at 19:16 UTC |