ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



10.2. Making Variables Private to a Function

Problem

Your subroutine needs temporary variables. You shouldn't use global variables, because another subroutine might also use the same variables.

Solution

Use my to declare a variable private to a region of your program:

sub somefunc {
    my $variable;                 # $variable is invisible outside somefunc()
    my ($another, @an_array, %a_hash);     # declaring many variables at once

    # ...
}

Discussion

The my operator confines a variable to a particular region of code in which it can be used and accessed. Outside that region, it can't be accessed. This region is called its scope.

Variables declared with my have lexical scope, which means that they exist only within a particular textual area of code. For instance, the scope of $variable in the Solution is the function it was defined in, somefunc. When a call to somefunc is made, the variable is created. The variable is destroyed when the function call ends. The variable can be accessed within the function, but not outside of it.

A lexical scope is usually a block of code with a set of braces around it, such as those defining the body of the somefunc subroutine or those marking the code blocks of if, while, for, foreach, and eval statements. Lexical scopes may also be an entire file or strings given to eval. Since a lexical scope is usually a block, we'll sometimes talk about lexical variables (variables with lexical scope) being only visible in their block when we mean that they're only visible in their scope. Forgive us. Otherwise, we'll be using the words "scope" and "sub" more than a WWII Navy movie.

Because the parts of code that can see a my variable are determined at compile time and don't change after that, lexical scoping is sometimes misleadingly referred to as static scoping. Lexical scoping is in contrast to dynamic scoping, which we'll cover in Recipe 10.13.

You can combine a my declaration with an assignment. Use parentheses when defining more than one variable:

my ($name, $age) = @ARGV;
my $start        = fetch_time();

These lexical variables behave as you would expect a local variable to. Nested blocks can see lexicals declared in outer blocks, but not in unrelated blocks:

my ($a, $b) = @pair;
my $c = fetch_time();

sub check_x {
    my $x = $_[0];       
    my $y = "whatever";  
    run_check();
    if ($condition) {
        print "got $x\n";
    }
}

In the preceding code, the if block inside the function can access the private $x variable. However, the run_check function called from within that scope cannot access $x or $y because run_check was presumably defined in another scope. However, check_x could access $a, $b, or $c from the outer scope because the function was defined in the same scope as those three variables.

Don't nest the declaration of named subroutines within the declarations of other named subroutines. Such subroutines, unlike proper closures, will not get the right bindings of the lexical variables. Recipe 10.16 shows how to cope with this restriction.

When a lexical goes out of scope, its storage is freed unless a reference to its value's storage space still exists, as with @arguments in the following code:

sub save_array {
    my @arguments = @_;
    push(@Global_Array, \@arguments);
}

Perl's garbage collection system knows not to deallocate things until they're no longer used. This is why we can return a reference to a private variable without leaking memory.

See Also

The section on "Scoped Declarations" in Chapter 2 of Programming Perl and the section on "Private Variables via my( )" in perlsub (1)


Previous: 10.1. Accessing Subroutine ArgumentsPerl CookbookNext: 10.3. Creating Persistent Private Variables
10.1. Accessing Subroutine ArgumentsBook Index10.3. Creating Persistent Private Variables