This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
preserve code blocks in interpolated qr//s
authorDavid Mitchell <davem@iabyn.com>
Wed, 30 Nov 2011 13:40:15 +0000 (13:40 +0000)
committerDavid Mitchell <davem@iabyn.com>
Wed, 13 Jun 2012 12:32:46 +0000 (13:32 +0100)
commitb30fcab9d36ac78789465635e3b1009dcf6a9488
tree51d56c1b6121b8316213dac288663448d33840b2
parent3d2bd50a8cb5045b534f6057d7efe9035e154cfa
preserve code blocks in interpolated qr//s

This now works:

    { my $x = 1; $r = qr/(??{$x})/ }
    my $x = 2;
    print "ok\n" if "1" =~ /^$r$/;

When a qr// is interpolated into another pattern, the pattern is still
recompiled using the stringified qr, but now the pre-compiled code blocks
from the qr are reused rather than being re-compiled, so it behaves like a
closure.

Note that this makes some tests in regexp_qr_embed_thr.t fail, due to a
pre-existing threads bug, which can be summarised as:

    use threads;
    my $s = threads->new(sub { return sub { $::x = 1} })->join;
    $s->();
    print "\$::x=[$::x]\n";

which prints undef, not 1, since the *::x is cloned into the child thread,
then cloned back into the parent as part of the CV (linked from the pad)
being returned in the join. The cloning/join code isn't clever enough
to realise that the back-cloned *::x is the same as the original *::x, so
the main thread ends up with two copies.

This manifests itself in the re tests as

    my $re = threads->new( sub { qr/(?{$::x = 1 })/ })->join();

where, since the returned qr// is now a closure, it suffers from the same
glob duplication in the parent.

So I've disabled 4 re_tests tests under threads for now.
regcomp.c
regcomp.h
regexec.c
regexp.h
t/re/pat_re_eval.t
t/re/re_tests
t/re/reg_eval_scope.t