Change 31824 by [EMAIL PROTECTED] on 2007/09/08 22:34:29 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]
Affected files ... ... //depot/perl/op.c#953 edit ... //depot/perl/pod/perldiag.pod#482 edit ... //depot/perl/t/op/state.t#16 edit Differences ... ==== //depot/perl/op.c#953 (text) ==== Index: perl/op.c --- perl/op.c#952~31823~ 2007-09-08 14:47:24.000000000 -0700 +++ perl/op.c 2007-09-08 15:34:29.000000000 -0700 @@ -3968,6 +3968,8 @@ } if (is_list_assignment(left)) { + static const char no_list_state[] = "Initialization of state variables" + " in list context currently forbidden"; OP *curop; PL_modcount = 0; @@ -4061,6 +4063,54 @@ o->op_private |= OPpASSIGN_COMMON; } + if ((left->op_type == OP_LIST + || (left->op_type == OP_NULL && left->op_targ == OP_LIST))) { + OP* lop = ((LISTOP*)left)->op_first; + while (lop) { + if (lop->op_type == OP_PADSV || + lop->op_type == OP_PADAV || + lop->op_type == OP_PADHV || + lop->op_type == OP_PADANY) { + if (lop->op_private & OPpPAD_STATE) { + if (left->op_private & OPpLVAL_INTRO) { + /* Each variable in state($a, $b, $c) = ... */ + } + else { + /* Each state variable in + (state $a, my $b, our $c, $d, undef) = ... */ + } + yyerror(no_list_state); + } else { + /* Each my variable in + (state $a, my $b, our $c, $d, undef) = ... */ + } + } else { + /* Other ops in the list. undef may be interesting in + (state $a, undef, state $c) */ + } + lop = lop->op_sibling; + } + } + else if (((left->op_private & (OPpLVAL_INTRO | OPpPAD_STATE)) + == (OPpLVAL_INTRO | OPpPAD_STATE)) + && ( left->op_type == OP_PADSV + || left->op_type == OP_PADAV + || left->op_type == OP_PADHV + || left->op_type == OP_PADANY)) + { + /* All single variable list context state assignments, hence + state ($a) = ... + (state $a) = ... + state @a = ... + state (@a) = ... + (state @a) = ... + state %a = ... + state (%a) = ... + (state %a) = ... + */ + yyerror(no_list_state); + } + if (right && right->op_type == OP_SPLIT && !PL_madskills) { OP* tmpop = ((LISTOP*)right)->op_first; if (tmpop && (tmpop->op_type == OP_PUSHRE)) { ==== //depot/perl/pod/perldiag.pod#482 (text) ==== Index: perl/pod/perldiag.pod --- perl/pod/perldiag.pod#481~31823~ 2007-09-08 14:47:24.000000000 -0700 +++ perl/pod/perldiag.pod 2007-09-08 15:34:29.000000000 -0700 @@ -1999,6 +1999,13 @@ The <-- HERE shows in the regular expression about where the problem was discovered. +=item 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-write C<state ($a) = 42> as +C<state $a = 42> to change from list to scalar context. Constructions such +as C<state (@a) = foo()> will be supported in a future perl release. + =item Insecure dependency in %s (F) You tried to do something that the tainting mechanism didn't like. ==== //depot/perl/t/op/state.t#16 (text) ==== Index: perl/t/op/state.t --- perl/t/op/state.t#15~31806~ 2007-09-06 10:30:57.000000000 -0700 +++ perl/t/op/state.t 2007-09-08 15:34:29.000000000 -0700 @@ -10,7 +10,7 @@ use strict; use feature ":5.10"; -plan tests => 108; +plan tests => 117; ok( ! defined state $uninit, q(state vars are undef by default) ); @@ -301,17 +301,6 @@ # -# List context reassigns, but scalar doesn't. -# -my @swords = qw [Stormbringer Szczerbiec Grimtooth Corrougue]; -foreach my $sword (@swords) { - state ($s1) = state $s2 = $sword; - is $s1, $swords [0], 'mixed context'; - is $s2, $swords [0], 'mixed context'; -} - - -# # Use with given. # my @spam = qw [spam ham bacon beans]; @@ -331,3 +320,28 @@ state $x = "two"; is $x, "two", "masked" } + +foreach my $forbidden (<DATA>) { + chomp $forbidden; + no strict 'vars'; + eval $forbidden; + like $@, qr/Initialization of state variables in list context currently forbidden/, "Currently forbidden: $forbidden"; +} +__DATA__ +state ($a) = 1; +(state $a) = 1; +state @a = 1; +state (@a) = 1; +(state @a) = 1; +state %a = (); +state (%a) = (); +(state %a) = (); +state ($a, $b) = (); +state ($a, @b) = (); +(state $a, state $b) = (); +(state $a, $b) = (); +(state $a, my $b) = (); +(state $a, state @b) = (); +(state $a, local @b) = (); +(state $a, undef, state $b) = (); +state ($a, undef, $b) = (); End of Patch.