On scope
Perl has two variable name scoping mechnisms: global and lexical. Declaration of lexical vars is done with my
, and they are accessibly by this name until they encounter a closing curly brace.
Global variables, on the other hand, are accessible from anywhere and do not have a scope. They can be declared with our
and use vars
, or do not have to be declared if strict
is not in effect. However, they have namespaces, or packages
. The namespace is a prefix seperated from the variable name by two colons (or a single quote, but never do that). Inside the package of the variable, the variable can be accessed with or without the prefix. Outside of the package, the prefix is required.
The local
function is somewhat special and gives global variables a temporary value. The scope of this value is the same as that of a lexical variable plus the scopes of all subs called within this scope. The old value is restored once this scope is exited. This is called the dynamic scope.
On Globs
Perl organizes global variables in a big hash representing the namespace and all variable names (sometimes called the stash). In each slot of this hash, there is a so-called glob. A typeglob is a special hash that has a field for each of Perls native types, e.g. scalar, array, hash, IO, format, code etc. You assign to a slot by passing the glob a reference of a value you want to add - the glob figures out the right slot on it's own. This is also the reason you can have multiple variables with the same name (like $thing
, @thing
, %thing
, thing()
). Typeglobs have a special sigil, namely the asterisk *
.
On no strict 'refs'
The no strict 'refs'
is a cool thing if you know what you are doing. Normally you can only dereference normal references, e.g.
my @array = (1 .. 5);
my $arrayref = \@array; # is a reference
push @{$arrayref}, 6; # works
push @{array}, 6; # works; barewords are considered o.k.
push @{"array"}, 6; # dies horribly, if strict refs enabled.
The last line tried to dereference a string, this is considered bad practice. However, under no strict 'refs'
, we can access a variable of which we do not know the name at compile time, as we do here.
Conclusion
The caller
functions returns the name of the package of the calling code, i.e. it looks up one call stack frame. The name is used here to construct the full names of $a
and $b
variables of the calling packages, so that they can be used there without a prefix. Then, these names are local
ly (i.e. in the dynamic scope) assigned to the reference of a newly declared, lexical variable.
The global variables $a
and $b
are predeclared in each package.
In the foreach
loop, these lexicals are assigned different values (lexical vars take precedence over global vars), but the global variables $foo::a
and $foo::$b
point to the same data because of the reference, allowing the anonymous callback sub in the reduce
call to read the two arguments easily. (See ikegamis answer for details on this.)
All of this hassle is good because (a) the effects are not externaly visible, and (b) the callback doesn't have to do tedious argument unpacking.