when anon subs are cloned, the 'assign once only' flag should be
Dave Mitchell [Mon, 10 Sep 2007 00:02:55 +0000 (00:02 +0000)]
set for all state vars in the pad.
(Nicholas worked up the same fix - spooky action at a distance!)

p4raw-id: //depot/perl@31835

pad.c
t/op/state.t

diff --git a/pad.c b/pad.c
index 44fafb6..6e33495 100644 (file)
--- 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])) {
index c372bf6..1c4fc8c 100644 (file)
@@ -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 (<DATA>) {
     chomp $forbidden;
     no strict 'vars';