I had to add a new feature to my Array::AsHash module. Basically, you might need to get keys and values at particular array indices (think "a list of pairs"), so I needed to allow this:
my $key = $array->key_at(2); my @keys = $array->key_at(0, 3, -1); my $keys = $array->key_at(0, 3, -1); # aref
So I wrote code like this (I did something similar for values):
sub key_at {
my $self = CORE::shift;
my $ident = ident $self;
my @keys;
foreach my $index (@_) {
$index *= 2;
CORE::push @keys => $array_for{$ident}[$index];
}
return wantarray ? @keys
: 1 == @_ ? $keys[0]
: \@keys;
}
See the bug? There are a couple of subtle issues here, but one of them is a real whopper. When you see it, you'll know.
FYI: The CORE:: stuff is there because I have methods named shift and push. ident is from Class::Std.
Re:Hmmm...
Ovid on 2006-03-04T01:43:12
Trust me. Once you see the bug, it's a forehead slapper -- if you've encountered this behavior before. It's something that folks often miss because it occurs so rarely, but it's a natural consequence of how Perl behaves.
D'oh!
rjray on 2006-03-10T20:14:36
*sound of forehead-slapping*Re:D'oh!
Ovid on 2006-03-10T20:19:34
Yeah, I know. It bit me, too
:)
Re:Yeah
Ovid on 2006-03-04T01:44:12
Right in one! Fortunately, the fix is trivial, but it's strange to see if folks don't know what's going on, so I document it.
Re:Yeah
Smylers on 2006-03-04T07:51:54
Why does Perl do this? It's bitten me in the ass a few times, and I can't seriously imagine using it deliberately in code to be maintained.I believe Larry also considers this to be a mistaken ‘feature’: in Perl 6
sbenyvnfrf ner ernq-bayl ol qrsnhyg, which would've avoided this bug.(The bit in italics is a spoiler for the original question, so I've put it in Welsh
... erm, I mean rot-13.) Smylers