Thursday, 7 June 2012

Perl: 'my' vs. 'local'

There's often a lot of confusion among new Perl hackers as to what the difference between my and local tags on variables. Unfortunately, many reach for the wrong one because the language that they're used to working with has local variables, and the words are deceptively familiar...

If you've just Google'd for a quick answer, you almost certainly want to be using my.

However, local's got to be there for a reason, right? Read on...

Here's a sample program that declares a variable, $global, that's visible to all of the subs beneath it. There's a function, print_global that displays its value, and two functions my_variable and local_variable that call it.

our $global = 'global';

sub print_global { print "\$global='$global'\n" }

sub my_variable {
  my $global = 'lexical';
  print_global;
}

sub local_variable {
  local $global = 'local';
  print_global;
}

my_variable();
local_variable();
 
The last two lines actually call the declared subs.

my_variable behaves exactly as you'd expect if you're coming from Java, C or a similar language. It's got a variable with the name $global in it, but when print_global is called, it's the the top-level $global (the string 'global') that gets displayed, as that's the one that's visible to that function. In this case, the variable called $global in my_variable isn't used anywhere and is wasted.

my variables are lexically scoped.

local_variable paints a different picture. local eclipses or shadows the globally visible $global, so that any function that subsequently asks for its value sees the shadowing value, not the previous value. This can happen repeatedly, so that there are a stack of shadowed values, with a single visible value.  So, the call to print_global from local_variable displays the string 'local'.

local variables are dynamically scoped.

Now, it's up to you to determine which you need.  But if you're reading this, I'll bet that it's my :-)