There is a restriction on arrays and hashes as state variables. We can't initialize them in list context as of Perl 5.10:
So
state @array = qw(a b c); #Error!
Why is it so? Why this is not allowed?
We can use state arrays and initialize them by this way
state @numbers;
push @numbers, 5;
push @numbers, 6;
but why not directly do it by state @numbers = qw(5 6);
Why doesn't Perl allow it?
According to perldiag, support for list context initialization is planned for a future release:
- Initialization of state variables in list context currently forbidden
(F) Currently the implementation of "state" only permits the initialization of scalar variables in scalar context. Re-writestate ($a) = 42
asstate $a = 42
to change from list to scalar context. Constructions such asstate (@a) = foo()
will be supported in a future perl release.
According to this message about the change that made this an error:
For now, forbid all list assignment initialisation of state variables, as the precise semantics in Perl 6 are not clear. Better to make it a syntax error, than to have one behaviour now, but change it later. [I believe that this is the consensus. If not, it will be backed out]
You could always use an arrayref instead:
state $arrayRef = [qw(a b c)];
Note that your example of
state @numbers;
push @numbers, 5;
push @numbers, 6;
does not mean the same thing that state @numbers = qw(5 6)
would (if it worked). A state
variable is only initialized once, but your code would push 5 & 6 onto the array every time that code was executed.
Horrible workaround:
state @array;
state $array_is_initialized;
unless ($array_is_initialized) {
$array_is_initialized = 1;
@array = (1,2,3);
}
It simply hasn't been written, because it's kind of hard, and getting it to work for scalars was considered to be more important. There's an opcheck (Perl_ck_sassign
in op.c
) that recognizes when the left side of an assignment is a padsv
op referring to a newly-declared state
variable and wraps it in a special once
op that makes sure that the assignment only happens once -- but it doesn't even attempt to recognize list assignments, probably due to the difficulty of breaking up a (state $a, my $b, state $c) = (1, 2, 3)
type construct. Funny though, it seems like state @a = qw(blah blah blah)
would be easy enough, and clearly it's a less pathological case than the other list assignment variant.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With