In Perl, packages are in effect namespaces, each with its own symbol table. They can also be used as classes in an OO context; see bless. When a package declaration is made, code from that declaration until the end of the innermost block, file, or eval will be carried out in that package. It is also possible to declare no package, in which case no relationship between the (nonexistent) package symbol table and the current variable-name mapping exists, and therefore variables must be either lexical, or with a specific package name given.
local, our, and use vars (and my, sort of) all affect the package symbol table's relationship with the current variable-name mapping, by locally assigning (our) a variable or typeglob name from/to the entry of the same name in the package symbol table, or globally assigning a variable name dynamically to the entry of the same name in whatever package happens to be current (use vars), or saving the state of a package variable and restoring it at the end of the block, file, or eval (local). my is a special case in that it assigns an unqualified variable name to a lexical variable, outside any package; this does not, strictly speaking, deal with the package's symbol table, but the distinction between lexical and package variables can be a source of confusion and is included here for completeness. Variables can also be explicitly specified as being from/in a certain package using a double-colon (::) or single quote (', highly deprecated and about to disappear in Perl 6).
If no package is declared, or given before the double-colon, package main is used.
Usage example:
use strict; # Currently in package main
package Foo; # Now in package Foo
use vars qw($u $v); # Causes $u or $v at any
# given point to refer to
# the $u or $v in the current
# package
$u = 5; # Sets $Foo::u
$Bar::u = 6; # Sets $Bar::u
$::u = 0; # Sets $main::u
{
package Bar; # Now in package Bar
{
our ($u); # Locally alias $u to $Bar::u
$u++; # Increments $Bar::u
}
$u++; # Error! The use vars
# does not carry across packages.
}
$u++; # Increments $Foo::u
# (block containing Bar has
# terminated)
my $u; # Lexical variable
{ # overshadows use vars
our ($u); # $u => $Foo::u (inner block
# overshadows
# outer block)
$u++; # Increments $Foo::u
}
$u++; # Increments lexical $u
package; # Null-package declaration
$v++; # Error! No package!
# (see use vars above)
$w++; # Error! No declaration!
# (see use strict above)
$Bar::v++ # This is qualified, so okay
my $w;
$w++; # This is now lexical, so okay
package Baz;
our ($w);
$w = 0;
sub w { $w }
w # Returns 0
{
local $w = 1; # Localizes entry
w # Returns 1; note dynamic scoping
}
w # Returns 0; block has terminated
{
my $w = 1; # Lexical declaration;
# does not affect $Baz::w
w # Returns 0, for that reason
}
Update: fixed an error, and another error (thanks, ariels).