Also, since C<$x> is lexical, it can't be reached or modified by any Perl
code outside.
-You can initialize state variables, and the assigment will be executed
-only once:
-
- sub starts_from_42 { state $x = 42; return ++$x }
-
-You can also, as a syntactic shortcut, initialize more than one if they're
-all declared within the same state() clause:
-
- state ($a, $b, $c) = ( 'one', 'two', 'three' );
-
-However, be warned that state variables declared as part of a list will
-get assigned each time the statement will be executed, since it will be
-considered as a regular list assigment, not one to be executed only once:
-
- (state $x, my $y) = (1, 2); # $x gets reinitialized every time !
-
-B<Caveat>: the code at the right side of the assignment to a state
-variable will be executed every time; only the assignment is disabled. So,
-avoid code that has side-effects, or that is slow to execute. This might
-be optimized out in a future version of Perl.
+When combined with variable declaration, simple scalar assignment to C<state>
+variables (as in C<state $x = 42>) is executed only the first time. When such
+statements are evaluated subsequent times, the assignment is ignored. The
+behavior of this sort of assignment to non-scalar variables is undefined.
=head3 Persistent variables with closures
local @oof = @bar; # make @oof dynamic, and init it
local $hash{key} = "val"; # sets a local value for this hash entry
+ delete local $hash{key}; # delete this entry for the current block
local ($cond ? $v1 : $v2); # several types of lvalues support
# localization
The behavior of local() on non-existent members of composite
types is subject to change in future.
+=head3 Localized deletion of elements of composite types
+X<delete> X<local, composite type element> X<local, array element> X<local, hash element>
+
+You can use the C<delete local $array[$idx]> and C<delete local $hash{key}>
+constructs to delete a composite type entry for the current block and restore
+it when it ends. They return the array/hash value before the localization,
+which means that they are respectively equivalent to
+
+ do {
+ my $val = $array[$idx];
+ local $array[$idx];
+ delete $array[$idx];
+ $val
+ }
+
+and
+
+ do {
+ my $val = $hash{key};
+ local $hash{key};
+ delete $hash{key};
+ $val
+ }
+
+except that for those the C<local> is scoped to the C<do> block. Slices are
+also accepted.
+
+ my %hash = (
+ a => [ 7, 8, 9 ],
+ b => 1,
+ )
+
+ {
+ my $a = delete local $hash{a};
+ # $a is [ 7, 8, 9 ]
+ # %hash is (b => 1)
+
+ {
+ my @nums = delete local @$a[0, 2]
+ # @nums is (7, 9)
+ # $a is [ undef, 8 ]
+
+ $a[0] = 999; # will be erased when the scope ends
+ }
+ # $a is back to [ 7, 8, 9 ]
+
+ }
+ # %hash is back to its original state
+
=head2 Lvalue subroutines
X<lvalue> X<subroutine, lvalue>
sub myreverse (@) myreverse $a, $b, $c
sub myjoin ($@) myjoin ":", $a, $b, $c
sub mypop (\@) mypop @array
- sub mysplice (\@$$@) mysplice @array, @array, 0, @pushme
+ sub mysplice (\@$$@) mysplice @array, 0, 2, @pushme
sub mykeys (\%) mykeys %{$hashref}
sub myopen (*;$) myopen HANDLE, $name
sub mypipe (**) mypipe READHANDLE, WRITEHANDLE
sub glob {
my $pat = shift;
my @got;
- local *D;
- if (opendir D, '.') {
- @got = grep /$pat/, readdir D;
- closedir D;
+ if (opendir my $d, '.') {
+ @got = grep /$pat/, readdir $d;
+ closedir $d;
}
return @got;
}