Perl foreach loop and dynamic scoping
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:
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:
Lessons learned:
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:
- 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).
- Reading the documentation (sometimes) helps.
Labels: perl, technology