subroutines intermediate

How to use state variables in Perl subroutines?

Question

How to use state variables in Perl subroutines?

Using state Variables in Perl Subroutines

Starting with Perl 5.10, the state keyword was introduced to declare persistent private variables inside subroutines. A state variable retains its value between calls to the subroutine, unlike a regular lexical variable declared with my which gets reinitialized on every call.

This makes state perfect for counters, memoization, caching, or any situation where you want private “static” variables similar to those in C or other languages.

How state differs from my and local

  • my: Creates a new lexical variable each time the subroutine is called. The variable is scoped to the block and does not retain value between calls.
  • local: Temporarily saves and replaces a global variable for dynamic scoping during a subroutine call.
  • state: Creates a lexical variable that is initialized only once and holds its state across multiple subroutine calls.

The main purpose of state is to have persistent private state that is not accessible outside the subroutine, avoiding pollution of the global namespace.

Example: Using a state variable as a counter

use strict;
use warnings;
use feature 'state';

sub call_counter {
    state $count = 0;          # initialized once
    $count++;                  # increment on each call
    return $count;
}

print "Call 1: ", call_counter(), "\n";
print "Call 2: ", call_counter(), "\n";
print "Call 3: ", call_counter(), "\n";

Explanation: On the first call, $count is initialized to zero and then incremented to 1. On subsequent calls, $count keeps the old value and increments it, resulting in 2, then 3, and so on. This illustrates how the value persists inside the subroutine without using any global variables.

Key Points and Gotchas

  • state variables require use feature 'state' or use 5.10.0; or later to enable the feature.
  • They can only be declared with state, not combined with other keywords like my state (just state is enough).
  • state variables are lexical to the subroutine; they cannot be accessed from outside.
  • If the state variable is a reference, beware of modifying the referenced data since changes persist.
  • state variables are initialized only once, the first time the subroutine is called.
  • Using state can be a cleaner alternative to using package globals or our variables for persistent state inside a subroutine.

Summary

The state keyword provides a simple way to maintain persistent private variables inside a subroutine in Perl 5.10 and later. It bridges the gap between a fresh lexical (my) variable on every call and a global variable. This is extremely useful for counters, caches, or any incremental computation needing to remember past state without exposing it globally.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 7ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Call 1: 1
Call 2: 2
Call 3: 3
STDERR
(empty)

Was this helpful?

Related Questions