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 AllenThread Next