10.3. Creating Persistent Private Variables
10.3.1. Problem
You want a variable to retain its
value between calls to a subroutine but not be visible outside that
routine. For instance, you'd like your function to keep track of how
many times it was called.
10.3.2. Solution
Wrap the function in another block, then declare
my variables in that block's scope rather than in
the function's:
{
my $variable;
sub mysub {
# ... accessing $variable
}
}
If the variables require initialization, make that block an INIT so
the variable is guaranteed to be set before the main program starts
running:
INIT {
my $variable = 1; # initial value
sub othersub {
# ... accessing $variable
}
}
10.3.3. Discussion
Unlike local[18] variables in
C or C++, Perl's lexical variables don't necessarily get recycled
just because their scope has exited. If something more permanent is
still aware of the lexical, it will stick around. In this code,
mysub uses $variable, so Perl
doesn't reclaim the variable when the block around the definition of
mysub ends.
[18]Technically speaking,
auto variables.
Here's how to write a counter:
{
my $counter;
sub next_counter { return ++$counter }
}
Each time next_counter is called, it increments
and returns the $counter variable. The first time
next_counter is called,
$counter is undefined, so it behaves as though it
were 0 for the ++. The variable is not part of
next_counter's scope, but rather part of the block
surrounding it. No code from outside can change
$counter except by calling
next_counter.Generally, you should use an INIT for the extra scope. Otherwise, you
could call the function before its variables were initialized.
INIT {
my $counter = 42;
sub next_counter { return ++$counter }
sub prev_counter { return --$counter }
}
This technique creates the Perl equivalent of C's static variables.
Actually, it's a little better: rather than being limited to just one
function, both functions share their private variable.
10.3.4. See Also
The sections on "Closures" in Chapter 8 of Programming
Perl and on "Avante-Garde Compiler, Retro Interpreter" in
Chapter 18 of Programming Perl; the section on
"Private Variables via my( )" in perlsub(1); the
section on "Package Constructors and Destructors" in
perlmod(1); Recipe 11.4