Perl repairs declared references to persistent state
Perl 5.39.3 makes declared references work with state variables and restores the global warning-disable contract. Both repairs concern interactions between features with distinct scopes.
A variable's scope and its lifetime answer different questions. Perl's state variables have lexical visibility but retain their values between calls. Declared-reference syntax adds another distinction, allowing a declaration to participate in operations on a reference to the declared variable. Combining those facilities exposed a missing case that Perl 5.39.3 now repairs.
The release history records this development snapshot on September 20. Its release notes say declared references can now be used with state. The change belongs to the interaction between existing facilities. It does not introduce persistent lexical storage as a new idea.
I tend to use Perl for compact text programs, where a small amount of retained state can be useful. Compactness still needs a precise meaning. A declaration that controls persistence should keep that meaning when another enabled feature changes how the declaration expresses a reference.
State retains a value without widening visibility
The version's subroutine reference explains that a state variable follows the lexical scoping rules of my. Its value persists across subroutine calls. A simple initializing assignment executes only the first time the declaration is evaluated.
That makes this documented pattern a private counter:
use feature 'state';
sub next_number {
state $number = 0;
return ++$number;
}
The variable remains inaccessible by its lexical name outside the subroutine. Persistence does not make it a package variable. Repeated calls operate on the retained value associated with that declaration.
For an anonymous subroutine, each created copy has its own state variable. Calls to one copy share that copy's state, while a separately created copy gets another state value. The reference explicitly distinguishes creating the anonymous subroutine from calling an existing copy.
That distinction matters for callback factories. A factory can return independent counters without exposing their variables as package state. The lifetime comes from the subroutine instance and the persistent declaration, while visibility remains lexical.
Declaring a reference changes the expression
The reference documentation describes the experimental declared_refs feature. It allows a backslash after a declaration keyword so that the declaration can express a reference to its variable. It is intended mainly for assignment-to-reference operations, including aliasing.
This is different from declaring an ordinary scalar and storing an unrelated reference in it. The backslash belongs to the declared-variable expression itself. The documentation illustrates that distinction by comparing my \$x with \my $x.
The feature can also apply selectively to entries in a declaration list. Some declared variables can appear directly, while others appear through a backslash. A reader therefore has to inspect the syntax of each declared item instead of assuming the list has one uniform reference behavior.
Perl 5.39.3 makes that syntax work with persistent state declarations. The repair aligns the implementation with the combination described in the reference. It does not remove the experimental status of declared references or replace the separate rules around reference assignment.
Aliasing still has its own limitations
The reference documentation warns that aliasing does not behave correctly with closures in certain cases. An alias established from an inner subroutine or eval can remain visible only inside that inner context and fail to affect the outer subroutine where the variables were declared. The documentation describes that behavior as subject to change.
A fix for state declarations should not be read as a resolution of that separate limitation. Persistent storage and alias visibility across nested execution contexts are different parts of the semantics. The new release note states the repaired declaration case without promising a general aliasing redesign.
The subroutine reference likewise says assignment behavior is undefined for state declarations whose assignment left side involves parentheses. That qualification belongs to the existing state facility. Combining features does not silently remove qualifications in either one's documentation.
I regard these boundaries as necessary context for the change. A development release can make an intended combination usable while leaving other experimental behavior unresolved. Describing exactly which combination now works gives module authors a more useful result than claiming broad reference support has become settled.
Global warning control regains its documented precedence
This release also fixes use 5.036 so that it respects -X. The command-line reference defines -X as disabling warnings globally, regardless of use warnings or $^W. Previously, the version declaration had failed to respect that global override.
This is another interaction between settings with different scopes. A source-level declaration can arrange language behavior and warnings for its code. The command-line flag states an overriding warning policy for the invocation. The fix restores the precedence promised by that flag.
Disabling warnings changes diagnostics, not whether a language construct is valid. A program should not infer that an experimental operation becomes supported because its warning is hidden. Similarly, respecting -X does not turn interpreter errors into successful operations. The repair concerns the documented global treatment of warnings.
Perl 5.39.3 makes these combinations more consistent at their existing boundaries. Persistent state can participate in declared-reference syntax, and a modern version declaration no longer defeats the command-line warning override. Each change preserves the separate meaning of the controls being combined.