develooper Front page | perl.perl5.porters | Postings from August 2011

semantics of (?{..}), lexicals and closures

Thread Next
From:
Dave Mitchell
Date:
August 15, 2011 03:13
Subject:
semantics of (?{..}), lexicals and closures
Message ID:
20110815101343.GC3179@iabyn.com
I've been giving some thought to the semantics behind re_evals, as regards
their behaviour regarding lexical vars and closure; i.e. when do they get
(re)compiled, and what instances of lexical vars to they capture each
time, etc.

I've worked this up into a big series of TODO tests in the davem/re_eval
branch, and the commit message (shown below) summarises the basic
principles of how I think it should eventually work.

Can anyone see anything wrong with this?

commit e04b85764f6d15d12d2a25b56d117f71c4ce6f51
Author:     David Mitchell <davem@iabyn.com>
AuthorDate: Mon Aug 8 17:56:10 2011 +0100
Commit:     David Mitchell <davem@iabyn.com>
CommitDate: Tue Aug 9 15:29:22 2011 +0100

    re_eval and closures: add lots of TODO tests
    
    re_evals currently almost always do the wrong thing as regards what
    lexical variable they refer to. This commit adds lots of TODO tests that
    show what behaviour I think there should be. Note that because hardly any
    of these tests pass yet, I haven't been able to verify whether they have
    any subtle typos etc.
    
    The basic philosophy behind these tests is:
    
    * literal code is compiled once at compile-time and shares the same
      lexical environment as its surroundings; i.e.
    
        /A(?{..$x..})B/
    
      is like
    
        /A/ && do {..$x..} && /B/
    
    * qr is treated as a closure: compiling once, but capturing its
      environment anew each time it is instantiated; i.e.
    
        for my $x (...) { push @r, qr/A(?{..$x..}B)/ }
    
      is like
    
        for my $x (...) { push @r, sub { /A/ && do {..$x..} && /B/ } }
    
    * run-time code is recompiled each time the regex is compiled; literal
      code in the same expression isn't recompiled; i.e.
    
        $code = '(?{ BEGIN{$y++} })';
        for (1..3) { /(?{ BEGIN{$x++}})$code/ }
        # x==1, y==3
    
    * an embedded qr is not stringified, so the qr retains its original
      lexical environment; i.e.
    
      $x = 1;
      { my $x = 2: $r = qr/(??{$x})/ }
      /A$r/; # matches A2, not A1


Affected files ...
    
    M	t/re/pat_re_eval.t


-- 
It's not that I'm afraid to die, I just don't want to be there when it
happens.
    -- Woody Allen

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About