From: Dave Mitchell Date: Mon, 10 Sep 2007 00:02:55 +0000 (+0000) Subject: when anon subs are cloned, the 'assign once only' flag should be X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0d3b281c4af2422da931f33692a278c5f05854cf;p=p5sagit%2Fp5-mst-13.2.git when anon subs are cloned, the 'assign once only' flag should be set for all state vars in the pad. (Nicholas worked up the same fix - spooky action at a distance!) p4raw-id: //depot/perl@31835 --- diff --git a/pad.c b/pad.c index 44fafb6..6e33495 100644 --- a/pad.c +++ b/pad.c @@ -1517,6 +1517,9 @@ Perl_cv_clone(pTHX_ CV *proto) else sv = newSV(0); SvPADMY_on(sv); + /* reset the 'assign only once' flag on each state var */ + if (SvPAD_STATE(namesv)) + SvPADSTALE_on(sv); } } else if (IS_PADGV(ppad[ix]) || IS_PADCONST(ppad[ix])) { diff --git a/t/op/state.t b/t/op/state.t index c372bf6..1c4fc8c 100644 --- a/t/op/state.t +++ b/t/op/state.t @@ -10,7 +10,7 @@ BEGIN { use strict; use feature ":5.10"; -plan tests => 119; +plan tests => 123; ok( ! defined state $uninit, q(state vars are undef by default) ); @@ -333,6 +333,21 @@ foreach my $spam (@spam) { is $f[1]->(), 1; } +# each copy of an anon sub should get its own 'once block' + +{ + my $x; # used to force a closure + my @f; + push @f, sub { $x; state $s = $_[0]; $s } for 1..2; + is $f[0]->(1), 1; + is $f[0]->(2), 1; + is $f[1]->(3), 3; + is $f[1]->(4), 3; +} + + + + foreach my $forbidden () { chomp $forbidden; no strict 'vars';