On Sat, Jun 13, 2020 at 1:27 PM Sean McAfee <eef...@gmail.com> wrote:

> On Sat, Jun 13, 2020 at 10:21 AM Brad Gilbert <b2gi...@gmail.com> wrote:
>
>> That was just a dumb example.
>> An incredibly dumb example.
>>
>> So what happens is that `Bool.pick` chooses The Bool values of either
>> `True` or `False`.
>> It does this at every position in the string.
>>
>>     'TrueFalse' ~~ / <{ Bool.pick }>
>>
>
> I saw this and figured that maybe a state variable could help:
>
>     'TrueFalse' ~~ /<{ $ //= Bool.pick }>/
>
> ...but it doesn't.  I suppose that means the bracketed code is not
> compiled just once, like an anonymous subroutine, but is fully re-evaluated
> on every match attempt.  Is that the intended behavior?
>

`state` variables act like they were declared in the next outer lexical
scope.

    {   {   state $v;  $v++   }   }
    {   my $v;   {   $v++   }   }

The next outer lexical scope that we see for `<{ }>` is the regex itself;

    / <{   $   //= Bool.pick   }> /
    / <{  (state $v)  //= Bool.pick }> /

That last one is almost like this:

    / :my $v;  <{  $v //= Bool.pick }> /

Almost.

It really acts like there is a scope defined by the <> and a separate one
defined by the {}.

(This may be just an implementation detail that is leaking out.)

---

At any rate the right way to fix it is to actually run `Bool.pick` exactly
once at the beginning.

    / :my $to-match = ~Bool.pick;  <{ $to-match }> /
    / :my $to-match = ~Bool.pick;  "$to-match" /

Reply via email to