After a discussion on the local perl monger's list, and a lesson from Brian McCauley, I wanted to summarize Perl scoping with some examples.

Two Ways...

This will come as no surprise to anyone familiar with Perl: there are two completely independent systems of scoping variables. In Perl a variable is either a "package variable" or a "lexical variable". A package variable is bound to a package name, while a lexical variable isn't in any package, but exists within syntactic bounds.

Packaged Sugar

Part of what makes this topic confusing is perl's helpfulness (note: always beware of machines that seem to be trying too hard to be helpful). For example, even when you don't declare a package, perl creates one for you named "main". Also, every non lexical symbol name is automatically given a package-name based on the current package, whenever you don't specify one yourself. These two actions make laziness an easy virtue to follow for the programmer.

For example, the following two programs are effectively the same...

$foo = 42;
package main;
$main::foo = 42;

In both of the above examples the variable $foois a "package variable" because it is bound to a package-name, either explicitly or by default. $foobelongs to the package symbol table mainin both cases. You can control this yourself...

package Choco;
$bar = "candy";  # sugary way of saying $Choco::bar

This is all very handy if you have more than one package, and don't want to have nasty namespace collisions...

package A;

$fru = 'apple';       # assumed to be $A::fru

package B;

print "1: $fru\n";    # assumed to be $B::fru
                      # but that doesn't exist here yet!

$fru = 'banana';      # assumed to be $B::fru

print "2: $A::fru\n"; # no namespace collisions here
print "3: $B::fru\n";
1:
2: apple
3: banana

Going Packageless

There are times when you don't want your variable to be visible in the package table. Often you want to limit the existence of a variable to just a small subroutine, and to not clutter up the the entire package. For that you can use "lexical variables" using the mykeyword.

my $dingaling = -1;

The $dingalingvariable is not in any package, not by default or otherwise. Don't even try to understand where it is, all you need to know is that it is in the ether. Lexicals live on an entirely different plane of existence than the package variables.

$fru    = "apple";   # assumed to be $main::fru
my $fru = "kumquat"; # not in main or any other package

The above program is perfectly valid and understandable (at least to perl). There are two completely separate variables there, but this leaves the question: which $fruis $fru? Well, as it happens, whenever it is ambiguous, perl first tries the lexical, and only if that doesn't exist will it then try the same symbol in the current package; or as my elementary school teacher would have sung it: "Whenever two variables go walkin', lex-uh-cal does all the talkin'..."

$fru    = "apple";   # assumed to be $main::fru
my $fru = "kumquat"; # lexical

print "1: $fru\n";   # which is it?
1: kumquat

Of course you can always specify the package variable explicitly, if that's what you really want. Package variables may be submissive, but they still answer when addressed by name...

$fru    = "apple";   #  assumed to be $main::fru
my $fru = "kumquat"; # lexical

print "1: $main::fru\n";   # yes, you, package variable
1: apple

Where Does It Stop?

The answer depends on what kind of variable you mean. Package variables, when addressed with their full package-name are accessible from anywhere (and so are sometimes called "global," a word that can lead to misunderstandings in Perl programmers who are either overly pedantic, or else not pedantic enough).

Lexical variables disappear (except in cases of closure, but that's another topic) at the end of their: code block, evaluated string or file, whichever comes first. Let's take those in order.

{
    my $dingaling = -1;
    print "1: $dingaling\n";
}

print "2: $dingaling\n"; # lexical is out of scope here
                         # and no $main::dingaling exists
1: -1
2:

Code blocks are limited to the space between braces, but effectively exist in evaluated strings too...

my $foo = 'banana';

$code = q(
    print "1: $foo\n";
    my $bar = 'apple';
);

eval $code;        # $foo is visible in there

print "2: $bar\n"; # but $bar is not visible out here
1: banana
2:

Finally, when defining lexicals in two different files, scope ends at the end of the file...

# in file one.pl
my $foo = 'banana'; # lexical
$bar = 'candy';     # assumed to be $main::bar
# in file two
require 'one.pl';
print "1: $foo\n"; # no $foo lexical here, and no $main::foo either
print "2: $bar\n"; # assumes you mean $main::bar which does exist
1:
2: candy

You can think of requireas a better way of slurping a file into a string and evaluating it, so the same scoping rules for an evaluated string apply here.

Acting Locally

You might logically assume that localwas The Way to restrict the scope of variables in Perl (you know, not global... "local"). But as you've just seen myis the tool for that job; so what's localfor?

To be clear, localdoes this: takes a variable and creates a copy of that variable, with the same name, in effect until the end of that scope. I know, that doesn't sound anything like what a localshould do, but it does, so get used to it. You might wonder what perl does with the original variable while this pretender is parading about town using it's name. Essentially it is holding the original behind its back, safely out of sight and ready to retake its rightful place as soon as the local doppelgänger version of itself goes out of scope. In this sense it kinda, sorta looks like the mycode we saw earlier, but now that you know what's going on behind the scenes, you should see right through that nonsense.

$id = 'Michael';       # a package variable, short for $main::id
print "1: I am $id\n";

{
    local $id = 'Lou'; # replaces $main::id but only in this scope
    print "2: I am $id\n";
}

print "3: I am $id\n";
1: I am Michael
2: I am Lou
3: I am Michael

We still have two kinds of variables: package and lexical -- that much is the same -- but now we have a way of temporarily creating a stand-in replacement for those package variables. If we were a little mad (and isn't it, to believe you're someone else?) we could combine all this into a program like so...

package main;

$id = 'Michael'; # a package variable, short for $main::id
print "1: I am $id\n";

{ # new block scope starts here
    local $id = 'Lou'; # replaces $main::id but only in this scope
    my $id = 'Myrtle'; # lexical, independent of the package variable
    
    print "2: I am $id\n"; # assumes you mean the lexical
    print "3: I am $main::id\n"; # explicitly the package variable now
                                 # but we get the local copy of it
    
} # scope ends, so does the lexical, and the local copy

print "4: I am $id\n"; # back to my old self again
1: I am Michael
2: I am Myrtle
3: I am Lou
4: I am Michael

If there isn't any package variable already in existence with that name, you can still create a local "version" of a brand new variable, which simply disappears at the end of its scope. In that case it looks even more like a lexical myvariable, but don't be fooled, it's still a package variable...

{
    local $pub = "The Vic";
    print "1: $pub!\n";
    print "2: $main::pub!\n";
}

print "3: $pub!\n";
print "4: $main::pub!\n";
1: The Vic
2: The Vic
3:
4: 

So when should you use localand when should you use my? The general rule is to use my, except when you can't, then use local. And you can't use myon special variables that belong to perl, like $/, @ARGV or the "operating system name" variable $^O.

print "1: I'm a $^O.\n";
        
{
    local $^O = "msdos";
    print "2: I'm a $^O.\n";
}

print "3: Just kidding, I'm still a $^O.\n";
1: I'm a linux.
2: I'm a msdos.
3: Just kidding, I'm still a linux.

Yours, Mine, and Ours

Just when you thought there were quite enough ways of doing it, Perl gives you one more in the bargain: our. Simply put, ourdeclares a package variable, with the added bonus that it can be referred to without it's package-name until the end of that block or file. Its not "local," its an ordinary package variable, only bestowed with special name powers. What that means is that, unlike other package variables, an ourpackage variable can be referred to by its short name across new package declarations but otherwise this power is lexical: it ends at the end of the block or file.

package Yard;
$cats = 2;           # $Yard::cats with the usual caveat that you
                     # can use its short name only in this package

our $house = "nice"; # $Yard::house but since it's ours you can use
                     # its short name throughout this block or file

package Other;
print "1: $cats\n";       # no lexical $cats so assumes $Other::cats
print "2: $Yard::cats\n"; # explicitly the $cats in the Yard

print "3: $house\n";      # no lexical or $Other::house, so our $house
print "4: $Yard::house\n";# explicitly, the $house in Yard package
1:
2: 2
3: nice
4: nice

The most useful job for ouris to shut use strictup when you want to use a package variable. We've all been lectured into typing those two words at the top of every script: use strictbut one of its jobs is to squawk whenever we declare a package variable without a package name. So this will immediately draw its ire...

use strict;
$house = "nice";
Global symbol "$house" requires explicit package name at script line 2.
Execution of script aborted due to compilation errors.

Well, you asked for it. You could calm strictdown by using the full package name all the time, but that gets old real quick...

package Dwellings::Abode::Humble;
use strict;

$Dwellings::Abode::Humble::house = "nice";
if ($Dwellings::Abode::Humble::house eq 'nice') {
    print "very, very $Dwellings::Abode::Humble::house.";
}

our suddenly seems like a pretty good idea now, doesn't it? Declare your package variable with ourand strictwill smile on approvingly when you use the shortened name.

package Dwellings::Abode::Humble;
use strict;

our $house = "nice"; # a package variable

if ($house eq 'nice') {
    print "very, very $house.";
}

A Matter of Privacy

The practical effect of declaring a variable with either myor ourbecomes important when writing code for external library files, for modules or in .pl files meant to be included with requireor do. Variables declared with myare lexical and not in any package, so have no package name and therefore cannot be directly referred to from outside their package. Variables declared with ourare package variables, and so can be referred to via their package-name, from any package. In this sense, the lexical variable is more private than the package variable: yet another good reason to use my.

# in file one.pl
package Little;

my $secret  = "my lips are sealed.";  # lexical
our $secret = "our little secret.";   # package
# in file two
package main;

require 'one.pl';

print "1: $secret\n";         # can't get to the lexical
print "2: $Little::secret\n"; # can get package variables
1:
2: our little secret.

Can't Get Enough?

For the wonk in you there is more detail to be had on Perl scoping. Try some of these...