How each drove me crazy
I had a program like this:
my @data = qw( bla fasel foo org jawohl hmblamm glfoo sdfoo sadfasffoo) ;my %regex = ( type1 => bla, type2 => foo);
foreach(@data) {
print $_,"\t";
print " matches " if test_it($_);
print "\n";
}sub test_it {
my $entry = shift;
while( my($type, $regex) = each %regex) {
return 1 if $entry =~ /$regex/;
}
return 0;
}
I expected:
bla matches
fasel
foo matches
org
jawohl
hmblamm matches
glfoo matches
sdfoo matches
sadfasffoo matches
but... I got not all matches.
Long story short: each does not reset the iterator for every call. And yes in modern versions of perl this behaviour is documented -- seems like I will stick with keys
Why not
values
? You’re not using the keys for anything.sub test_if {
my $entry = shift;
return List::Util::first { $entry =~ /$_/ } values %regex;
}
Also see Do not use each
Actually this is a case where
each
could be fine, because the loop body is not making any calls to other code that could be messing with the hash’s iterator. He just has to reset the iterator every time he wants to start over:Of course since he doesn’t use the keys in this example, it’s a pointless exercise to use
each
rather thanvalues
. (Well, if%regex
is expected to grow huge theneach
will take much less memory than making a list of all thevalues
, and would be faster too if a match is found quickly.)