More on foreach localisation

Wednesday 9 September 2009 @ 6:47 am

This was first time I encountered the strange foreach localisation.

One day I was using global var in script (lame, I know). I wanted to use it in foreach. And its value magically disappeared when called other subroutine. This was strange.

This was a script to make reports for customers. The code looked like this (many parts taken out for brevity and to protect the innocent 😉 ) :

use strict;
use warnings;
my $custid; # to store customerid.
my %rep_conf;
(...more config data kept in that hash...)
my $cust_name; # customer name
foreach $cust_name (keys %rep_conf) { # in that hash we get report configuration. The key was customer name.
  print("$cust_name"); # here is still exists
  $custid = $rep_conf{$cust_name}{'custid'}; # customer id was taken from config hash
  $firstsheet = &get_sheet; # get data for our report
sub get_sheet {
  print($custid); # works
  print($cust_name); # empty. WTF?

I scratched my head – why the $custid value exists and $cust_name value disappeared?

I had I hunch to read about foreach in perl docs:

The foreach loop iterates over a normal list value and sets the variable VAR to be each element of the list in turn. If the variable is preceded with the keyword my, then it is lexically scoped, and is therefore visible only within the loop.

Sounds rational. But it was no “my” there:
foreach $cust_name (keys %rep_conf)

Otherwise, the variable is implicitly local to the loop and regains its former value upon exiting the loop.
If the variable was previously declared with my, it uses that variable instead of the global one, but it’s still localized to the loop. This implicit localisation occurs only in a foreach loop.

Here is the mystery solved.  Strange indeed – only for/foreach loop behaves like this.

Tags: ,

Comments (1) - Posted in wtf by  

Warning: Creating default object from empty value in /home3/lech/public_html/ on line 1057

 One response to “More on foreach localisation”

Leave a comment