Skip to content

Latest commit

 

History

History
359 lines (264 loc) · 9.74 KB

scope.pod

File metadata and controls

359 lines (264 loc) · 9.74 KB

Scope

Scope in Perl refers to the lifespan and visibility of symbols. 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

The most common form of scoping in modern Perl is lexical scoping. The Perl compiler resolves this scope during compilation. This scope is visible as you read a program. 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; these are 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. Thus, in the code:

... $outer is visible in all four scopes. $inner is visible in the method, the do block, and the for loop. $do_scope is visible only in the do block and $for_scope 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 and not vampires, if you must know.. Even though redeclaring a lexical variable with the same name and type in a single lexical scope produces a warning message, shadowing a lexical in a nested scope does not; this is a feature of lexical shadowing.

Lexical declaration has its subtleties. For example, a lexical variable used as the iterator variable of a for loop has a scope within the loop block. It is not visible outside the block:

Similarly, the given construct creates a lexical topic (akin to my $_) within its block:

... despite assignment to $_ inside the block. You may explicitly lexicalize the topic yourself, though this is more useful when considering dynamic scope.

Finally, lexical scoping facilitates closures (closures). Beware creating closures accidentally.

Our Scope

Within a given scope, you may 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.

The best use of our is for variables you absolutely must have, such as $VERSION.

Dynamic Scope

Dynamic scope resembles lexical scope in its visibility rules, but instead of looking outward in compile-time scopes, lookup happens along the current calling context. Consider the example:

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--at the point of exiting the block containing the localization of $scope, Perl restores the original value of the variable. The final say prints outer scope once again.

While the variable is visible within all scopes, the value of the variable changes depending on localization and assignment. This feature can be tricky and subtle, but it is especially useful for changing the values of magic variables.

This difference in visibility between package variables and lexical variables is apparent in the different storage mechanisms of these variables within Perl 5 itself. 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 is how a function can call itself and not clobber the values of existing variables.)

Package variables have a storage mechanism called symbol tables. Each package has a single symbol table, and every package variable has an entry in this table. You can inspect and modify this symbol table from Perl; this is how importing works (importing). This is also why you may only localize global and package global variables and never lexical variables.

It's common to localize several 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.

These are all special global variables; localizing them in the narrowest possible scope will avoid the action at a distance problem of modifying global variables used other places in your code.

State Scope

A final type of scope is new as of Perl 5.10. This is the scope of the state builtin. State scope resembles lexical scope in that it declares a lexical variable, but the value of that variable gets initialized once, and then persists:

On the first call to state, $count has never been initialized, so Perl executes the assignment. The program prints 1, 2, and 3. If you change state to my, the program will print 1, 1, and 1.

You may also use an incoming parameter to set the initial value of the state variable:

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. This behavior is as intended and documented, though its implementation can lead to surprising results:

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--not because the integers are the second arguments passed, but because the shift of the first argument only happens in the first call to counter().

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.

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

A non-empty Z<>

Around line 185:

A non-empty Z<>

Around line 286:

A non-empty Z<>