Persistent, Private Variables
With my we were able to
make variables private to a subroutine, although each time we called the
subroutine we had to define them again. With state, we can still have private variables
scoped to the subroutine but Perl will keep their values between
calls.
Going back to our first example in this chapter, we had a
subroutine named marine that
incremented a variable:
sub marine {
$n += 1; # Global variable $n
print "Hello, sailor number $n!\n";
}Now that we know about strict,
we add that to our program and realize that our use of the global
variable $n isn’t allowed anymore. We
can’t make $n a lexical variable with
my because it wouldn’t retain its
value.
Declaring our variable with state tells Perl to
retain the variable’s value between calls to the subroutine and to make
the variable private to the subroutine:
use 5.010;
sub marine {
state $n = 0; # private, persistent variable $n
$n += 1;
print "Hello, sailor number $n!\n";
}Now we can get the same output while being strict-clean and
not using a global variable. The first time we call the subroutine, Perl
declares and initializes $n. Perl
ignores the statement on all subsequent calls. Between calls, Perl
retains the value of $n for the next
call to the subroutine.
We can make any variable type a state variable; it’s not just for scalars.
Here’s a subroutine that remembers its arguments and provides a running
sum by using a state array:
use 5.010; running_sum( 5, 6 ); running_sum( 1..3 ); running_sum( 4 ); ...