Thursday, March 25, 2010

 

Perl foreach loop and dynamic scoping

Looping over a list of two values in Perl with for or foreach would seem trivial. What if the code suddenly appears stuck at the first value? That's exactly what happened with the Perl script below:

my $PROTOCOL = 'http';
for $PROTOCOL (qw(http https)) {
dosomething();
}

sub dosomething {
print "$PROTOCOL\n";
}

Even with use strict and warnings turned on, the script runs without warnings, but rather than printing http and https in sequence, it prints http twice!

As it turns out, after much debugging (the sample code is stripped down from a larger script which actually does something useful) and collectively scratching heads, this is indeed the documented behavior:
The foreach loop defaults to scoping its index variable dynamically in the manner of local. However, if the index variable is prefixed with the keyword my, or if there is already a lexical by that name in scope, then a new lexical is created instead.

Lessons learned:
  1. After a decade of hacking Perl code, there's always something new to learn (and use strict doesn't stop the programmer from getting the scoping wrong).
  2. Reading the documentation (sometimes) helps.

Labels: ,








Page tools



Archives