start page | rating of books | rating of authors | reviews | copyrights

Perl CookbookPerl CookbookSearch this book

10.2. Making Variables Private to a Function

10.2.1. Problem

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

10.2.2. 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

    # ...
}

10.2.3. 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, meaning that they exist only within a specific textual region of code. For instance, the scope of $variable in the Solution is the function it was defined in, somefunc. The variable is created when somefunc is entered, and it is destroyed when the function returns. The variable can be accessed only from inside the function, not from outside.

A lexical scope is usually a block of code with 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. An entire source file and the string argument to eval are each a lexical scope;[17] think of them as blocks with invisible braces delimiting their confines. Because a lexical scope is most often found as a brace-delimited block, when discussing lexical variables we sometimes say that they are visible only in their block, but what we really mean is that they're visible only in their scope.

[17]Although not of the same sort: the eval scope is a nested scope, just like a nested block, but the file scope is unrelated to any other.

The code that can legally access a my variable is determined statically at compile time and never changes, and so lexical scoping is sometimes referred to as static scoping, especially when in contrast to dynamic scoping, a topic 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 of a local variable. Nested blocks can see lexicals declared in enclosing, 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 can 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 definitions of named subroutines. If you do, they won't get the right bindings of the lexical variables. Recipe 10.16 shows how to cope with this restriction.

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

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

This code creates a new array each time save_array is called, so you don't have to worry that it'll reuse the same array each time the function is called.

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

10.2.4. See Also

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



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.