Freitag, 19. Juni 2009

Perl Gotcha II

Don't exit an each loop unless you really know what you do.
Consider the following code



1 my %h = ( one => 1, two => 2, three => 3 );
2 sub find_key {
3 my $val = shift;
4 while ( my ($k,$v) = each %h ) {
5 return $k if $v == $val;
6 }
7 }
8 find_key(2) eq 'two' or die "key not found";
9 # and again
10 find_key(2) eq 'two' or die "key not found";


The call to find_key in line 10 fails, because it does not iterate through %h again, but continues where the last each call left off.

This is the documented behavior, but one might not expect it.
perldoc says:

The next call to "each" after that will start iterating again. There is a
single iterator for each hash, shared by all "each", "keys", and "values"
function calls in the program; it can be reset by reading all the elements
from the hash, or by evaluating "keys HASH" or "values HASH".

Mittwoch, 17. Juni 2009

Perl Gotcha I

I'm trying to write some interesting, sometimes unexpected, things one can experience with Perl in the next time.
They are partly based on a talk I did at the German Perl Workshop 2008, see my talk in german.


How does the regex
  m/foo$\nbar/m
gets interpreted?


At first it looks like it matches "foo", then end of line with the $, then a newline with \n and finally "bar".
Let' see:
  my $string = "foo\nbar";
print $string =~/foo$\nbar/m ? 'match':'no match'
Surprisingly the regex does not match like expected.


Explanation:
The regex is interpreted as
  /foo $\ nbar/mx
e.g. it matches "foo", then the content of the special variable $\ (usually undef) and finally "nbar"