develooper Front page | perl.perl5.porters | Postings from March 2003

Re: (?{ .. })'s and lexicals: A fix ([perl #9010], [perl #8817], [perl #8030], etc)

Thread Previous | Thread Next
Dave Mitchell
March 16, 2003 04:58
Re: (?{ .. })'s and lexicals: A fix ([perl #9010], [perl #8817], [perl #8030], etc)
Message ID:
On Sun, Mar 16, 2003 at 08:00:18AM +0200, Enache Adrian wrote:
> $ perl -le 'sub a { my $p; /(?{ print ++$p })/ } a, a, a' 
> 1
> 2
> 3
> That should print '1' each time.
> This seems to be a very old bug ( see the subject line ).

It all rather depends on how you view the code within the regex - whether
it is a block or a sub. Currently Perl5 treats it as a closure (in a
half-baked way), so

    sub a { my $x = shift; /(?{ $x })/ }

acts roughly like like

    sub a { my $x = shift; sub closure { $x }; /(?{ closure() })/ }

(In fact with my recent closure patch, that first code example actually
gives a 'variable will not stay shared' warning.)

In the example you give it could be argued that it should be treated
like a block, but in the case of qr//, it seems more natural to treat
it as a sub, since the flow of control is independent of the sub
in which the regex is compiled:

    sub a { my $x = shift; qr/(?{ $x })/ }
    my $rex = a(42);

which seems to be the moral equivalent of

    sub a { my $x = shift; sub { $x } }
    my $sub = a(42);

Perhaps bare regexs should be demoted to blocks and qr// should be
promoted to full anon sub status, so that they get cloned on each execution
of qr// ???

Although I have to say that personally I don't like the idea of sharing
the same pad, simply becuase of run-time compilation, eg

    for (1..1_000_000) {
	$p = '(?{my $x; ...})'; /$p/;

This causes the pad to get filled with a million slots for defunct $x's.
Eval's have their own pad to avoid this sort of thing.

> The PAD_SAVE_LOCAL, PAD_RESTORE_LOCAL macros at the EVAL: case
> in S_regmatch() aren't at all useful: they don't free the lexicals
> in the pad, they only switch pads.

I added those two macros; but they were added purely to formalise the
exisitng behaviour of /(?{})/. If we move either to sharing the same pad
or full closure, they can be removed.

Lady Nancy Astor: If you were my husband, I would flavour your coffee
with poison.
Churchill: Madam - if I were your husband, I would drink it.

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About