Skip to content

Latest commit

 

History

History
363 lines (264 loc) · 9.35 KB

scope.pod

File metadata and controls

363 lines (264 loc) · 9.35 KB

Scope

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

"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:

This program prints Edward and then JacobFamily 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 (akin to 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).

Our Scope

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 such as $VERSION and $AUTOLOAD.

Dynamic Scope

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 localization 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 localizes 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 localized $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 localize 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 selected filehandle after every write operation.

localizing these in the narrowest possible scope limits the effect of your changes. This can prevent strange behavior in other parts of your code.

State Scope

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:

POD ERRORS

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 110:

Deleting unknown formatting code N<>

Around line 166:

A non-empty Z<>

Around line 181:

A non-empty Z<>

Around line 274:

A non-empty Z<>