The patch below fixes the immediate problem, but closures within
(?{}) are still broken by design due to the way that the parent CV is
thrown away but the pad is held onto, and the way that scoping works (or
doesn't work, more to the point). I don't intend to fix this more
deep-deated malaise in the near future!
Eg the following:
our $count = 10;
our @subs;
"abcd" =~ /.+(?{ my $x = $count++; push @subs, sub {0+$x}}).../;
printf "val=[%s]\n", $_->() for @subs;
produces:
$ perl580 /tmp/p
val=[0]
val=[0]
val=[0]
val=[0]
$ bleedperl /tmp/p
val=[0]
val=[0]
val=[0]
val=[0]
$ bleedperl-debugging /tmp/p
Assertion !((sv)->sv_flags & 0x00000100) failed: file "pad.c", line 1427 at (re_eval 1) line 2.
all of which are wrong in their different ways.
Dave.
--
This is a great day for France!
-- Nixon at Charles De Gaulle's funeral
Change 22445 by davem@davem-percy on 2004/03/06 15:25:32
fix coredump in /(?{sub{}})/
Affected files ...
... //depot/perl/pad.c#29 edit
Differences ...
==== //depot/perl/pad.c#29 (text) ====
@@ -257,8 +257,11 @@
CV *innercv = (CV*)curpad[ix];
namepad[ix] = Nullsv;
SvREFCNT_dec(namesv);
- curpad[ix] = Nullsv;
- SvREFCNT_dec(innercv);
+
+ if (SvREFCNT(comppad) < 2) { /* allow for /(?{ sub{} })/ */
+ curpad[ix] = Nullsv;
+ SvREFCNT_dec(innercv);
+ }
if (SvREFCNT(innercv) /* in use, not just a prototype */
&& CvOUTSIDE(innercv) == cv)
{