Scope in Perl refers to the lifespan and visibility of named entities. Everything with a name in Perl (a variable, a function) has a scope. Scoping helps to enforce encapsulation--keeping related concepts together and preventing them from leaking out.
Lexical scope is the scope visible as you read a program. The Perl compiler resolves this scope during compilation. A block delimited by curly braces creates a new scope, whether a bare block, the block of a loop construct, the block of a sub
declaration, an eval
block, or any other non-quoting block.
Lexical scope governs the visibility of variables declared with my
--lexical variables. A lexical variable declared in one scope is visible in that scope and any scopes nested within it, but is invisible to sibling or outer scopes:
... $battery_level
is visible in all four scopes. $timer
is visible in the method, the do
block, and the for
loop. $dustpan
is visible only in the do
block and $polish_cloth
within the for
loop.
Declaring a lexical in an inner scope with the same name as a lexical in an outer scope hides, or shadows, the outer lexical within the inner scope. This is often what you want:
This program prints Edward
and then Jacob
Family members, not vampires., even though redeclaring a lexical variable with the same name and type in the same lexical scope produces a warning message. Shadowing a lexical is a feature of encapsulation.
Some lexical declarations have subtleties, such as a lexical variable used as the iterator variable of a for
loop. Its declaration comes outside of the block, but its scope is that within the loop block:
Similarly, given
(given_when) creates a lexical topic (like my $_
) within its block:
... such that leaving the block restores the previous value of $_
.
Functions--named and anonymous--provide lexical scoping to their bodies. This facilitates closures (closures).
Within given scope, declare an alias to a package variable with the our
builtin. Like my
, our
enforces lexical scoping of the alias. The fully-qualified name is available everywhere, but the lexical alias is visible only within its scope.
our
is most useful with package global variables like $VERSION
and $AUTOLOAD
.
Dynamic scope resembles lexical scope in its visibility rules, but instead of looking outward in compile-time scopes, lookup traverses backwards through the calling context. While a package global variable may be visible within all scopes, its value changes depending on local
ization and assignment:
The program begins by declaring an our
variable, $scope
, as well as three functions. It ends by assigning to $scope
and calling main()
.
Within main()
, the program prints $scope
's current value, outer scope
, then local
izes the variable. This changes the visibility of the symbol within the current lexical scope as well as in any functions called from the current lexical scope. Thus, $scope
contains main() scope
within the body of both middle()
and inner()
. After main()
returns, when control flow reaches the end of its block, Perl restores the original value of the local
ized $scope
. The final say
prints outer scope
once again.
Package variables and lexical variables have different visibility rules and storage mechanisms within Perl. Every scope which contains lexical variables has a special data structure called a lexical pad or lexpad which can store the values for its enclosed lexical variables. Every time control flow enters one of these scopes, Perl creates another lexpad for the values of those lexical variables for that particular call. This makes functions work correctly, especially in recursive calls (recursion).
Each package has a single symbol table which holds package variables as well as named functions. Importing (importing) works by inspecting and manipulating this symbol table. So does local
. You may only local
ize global and package global variables--never lexical variables.
local
is most often useful with magic variables. For example, $/
, the input record separator, governs how much data a readline
operation will read from a filehandle. $!
, the system error variable, contains the error number of the most recent system call. $@
, the Perl eval
error variable, contains any error from the most recent eval
operation. $|
, the autoflush variable, governs whether Perl will flush the currently select
ed filehandle after every write operation.
local
izing these in the narrowest possible scope limits the effect of your changes. This can prevent strange behavior in other parts of your code.
Perl 5.10 added a new scope to support the state
builtin. State scope resembles lexical scope in terms of visibility, but adds a one-time initialization as well as value persistence:
On the first call to counter
, Perl performs its single initialization of $count
. On subsequent calls, $count
retains its previous value. This program prints 1
, 2
, and 3
. Change state
to my
and the program will print 1
, 1
, and 1
.
You may use an expression to set a state
variable's initial value:
Even though a simple reading of the code may suggest that the output should be 2
, 4
, and 6
, the output is actually 2
, 3
, and 4
. The first call to the sub counter
sets the $count
variable. Subsequent calls will not change its value.
state
can be useful for establishing a default value or preparing a cache, but be sure to understand its initialization behavior if you use it:
The counter for this program prints 2
, 3
, and 4
as expected, but the values of the intended second arguments to the counter()
calls are two
, 4
, and 6
--because the shift
of the first argument only happens in the first call to counter()
. Either change the API to prevent this mistake, or guard against it with:
Hey! The above document had some coding errors, which are explained below:
- Around line 3:
-
A non-empty Z<>
- Around line 15:
-
A non-empty Z<>
- Around line 96:
-
Deleting unknown formatting code N<>
- Around line 145:
-
A non-empty Z<>
- Around line 160:
-
A non-empty Z<>
- Around line 250:
-
A non-empty Z<>