
![]() | ![]() |
10.13. Saving Global Values
10.13.1. Problem
You need to temporarily save
away the value of a global variable.
10.13.2. Solution
Use the
local operator to save a previous global value,
automatically restoring it when the current block exits:our $age = 18; # declare and set global variable
if (CONDITION) {
local $age = 23;
func( ); # sees temporary value of 23
} # Perl restores the old value at block exit
10.13.3. Discussion
Despite its name, Perl's local operator does not
create a local variable. That's what my does.
Instead, local merely preserves an existing value
for the duration of its enclosing block. Hindsight shows that if
local had been called
save_value instead, much confusion could have
been avoided.Three places where you must use
local instead of my are:
You need to give a global variable a temporary value, especially
$_.
You need to create a local file or directory handle or a local
function.
You want to temporarily change just one element of an array or hash.
10.13.3.1. Using local( ) for temporary values for globals
The first situation is more apt to
happen with predefined, built-in variables than with user variables.
Often these are variables that Perl consults for hints for its
high-level operations. In particular, any function that uses
$_, implicitly or explicitly, should certainly
have a local $_. This is annoyingly easy to forget
to do. See Recipe 13.15 for one solution to
this.Another common target for local is the
$/ variable, a global that implicitly affects the
behavior of the readline operator used in
<FH> operations.$para = get_paragraph(*FH); # pass filehandle glob
$para = get_paragraph(*FH); # pass filehandle by glob reference
$para = get_paragraph(*IO{FH}); # pass filehandle by IO reference
sub get_paragraph {
my $fh = shift;
local $/ = '';
my $paragraph = <$fh>;
chomp($paragraph);
return $paragraph;
}
10.13.3.2. Using local( ) for local handles
The
second situation used to arise whenever you needed a local filehandle
or directory handle—or more rarely, a local function.$contents = get_motd( );
sub get_motd {
local *MOTD;
open(MOTD, "/etc/motd") or die "can't open motd: $!";
local $/ = undef; # slurp full file;
local $_ = <MOTD>;
close (MOTD);
return $_;
}
If
you wanted to return the open filehandle, you'd use:return *MOTD;
However, in modern releases of Perl, you would make use of the
filehandle autovivification property:$contents = get_motd( );
sub get_motd {
my $motd; # this will be filled in by the next line
open($motd, "/etc/motd") or die "can't open motd: $!";
local $/ = undef; # slurp full file;
return scalar <$motd>;
}
When the function returns, the anonymous filehandle is automatically
closed for you. However, if you'd chosen to return
$motd, then it wouldn't be. This is explained more
fully in the Introduction to Chapter 7.
10.13.3.3. Using local( ) on parts of aggregates
The third situation is exceedingly rare, except for one common case.
Because the local operator is really a "save value" operator, you can
use it to save off just one element of an array or hash, even if that
array or hash is itself a lexical!my @nums = (0 .. 5);
sub first {
local $nums[3] = 3.14159;
second( );
}
sub second {
print "@nums\n";
}
second( );
0 1 2 3 4 5
first( );
0 1 2 3.14159 4 5
The only common use for this kind of thing is for temporary signal
handlers.sub first {
local $SIG{INT} = 'IGNORE';
second( );
}
Now while second is running, interrupt signals are
ignored. When first returns, the previous value of
$SIG{INT} is automatically restored.Although a lot of old code uses local, it's
definitely something to steer clear of when it can be avoided.
Because local still manipulates the values of
global variables, not local variables, you'll run afoul of
use strict unless you declared
the globals using our or the older
use vars.
The
local operator produces dynamic
scoping or runtime scoping. This
is in contrast with the other kind of scoping Perl supports, which is
much more easily understood. That's the kind of scoping that
my provides, known as lexical
scoping, or sometimes as static or
compile-time scoping.With dynamic scoping, a variable is accessible if it's found in the
current scope—or in the scope of any frames (blocks) in its
entire subroutine call stack, as determined at runtime. Any functions
called have full access to dynamic variables, because they're still
globals, just ones with temporary values. Only lexical variables are
safe from such tampering.Old code that says:sub func {
local($x, $y) = @_;
#....
}
can almost always be replaced without ill effect by the following:sub func {
my($x, $y) = @_;
#....
}
The only case where code can't be so upgraded is when it relies on
dynamic scoping. That would happen if one function called another,
and the latter relied upon access to the former's temporary versions
of the global variables $x and
$y. Code that handles global variables and expects
strange action at a distance instead of using proper parameters is
fragile at best. Good programmers avoid this kind of thing like the
plague. (The solution is to explicitly pass values as parameters,
rather than storing them in shared global variables.)If you come across old code that uses:&func(*Global_Array);
sub func {
local(*aliased_array) = shift;
for (@aliased_array) { .... }
}
this should probably be changed into something like this:func(\@Global_Array);
sub func {
my $array_ref = shift;
for (@$array_ref) { .... }
}
They're using the old pass-the-typeglob strategy devised before Perl
supported proper references. It's not a pretty thing.
10.13.4. See Also
The local, my, and
our functions in Chapter 29 of
Programming Perl and
perlfunc(1); Chapter 6 of Programming
Perl; the section on "Scoped Declarations" in Chapter 4
of Programming Perl; the sections on "Private
Variables via my( )" and "Temporary Values via local( )" in
perlsub(1); Recipe 10.2;
Recipe 10.16
![]() | ![]() | ![]() |
10.12. Handling Exceptions | ![]() | 10.14. Redefining a Function |

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