Hi Joe,

Yup, your test file works perfectly:

Last login: Thu Jun 18 19:38:12 on ttys000
user@mbook:~$ perl6  regexp_code_interpolation_with_capture_var.t
ok 1 - case: {} $(... $0 ...)
ok 2 - case: <{... $0 ... .subst(/\s/, '\s', :g)}>
ok 3 - case: {} "... $0 ..." (brad gilbert rec)
ok 4 - case: {} $( ... ) with named capture
ok 5 - case: {} $( subcall( $0 ) )
ok 6 - case: {} "&subcall( $0 )"
user@mbook:~$ perl6 --version
This is Rakudo version 2020.02.1.0000.1 built on MoarVM version 2020.02.1
implementing Raku 6.d.
user@mbook:~$

I'm sure I checked the previous code numerous times, so I'm wondering
if it's an issue specific to MoarVM version 2020.02.1 ? Anyway, I had
quite forgotten that you had updated to 2020.05.1 (I thought you were
still on 2019.03.1).

FYI, I had been trying to write a line of code that calls the ".words"
method on both the input lines and your product list, but for some
reason I haven't been able to get to work. Maybe it's time for me to
update, as well.

Best, Bill.



On Thu, Jun 18, 2020 at 2:25 PM Joseph Brenner <doom...@gmail.com> wrote:
>
> I don't have a 2020.02.1 around, but I see all of this working
> with both more recent and earlier versions: 2020.05.1 and 2019.03.1.
>
> > 1. I got your first "if" line (below) from June 14th to work, the one
> > you said, "it's not a complete solution":
> > 1> if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s+/, '\s', :g) }> / {
>
> The reason it's "not complete", by the way is that it only covers the
> case of spaces when in principle the product descriptions might
> include any regexp meta-character, e.g. "*", "+", "(", ")", etc.  Even
> a hyphen, "-" can mess things up.
>
> It's also pretty ugly, and arguably not complete in other ways,  it
> would probably make more sense to drop the "+" in the subst pattern.
> And really every one of my examples should've pinned the whole
> expression with a trailing $ to make it an exact match on the
> description field:
>
>     if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s/, '\s', :g)
> }> \s* $ / {
>
> I'm attaching a test file that exercises this stuff... if you get a
> chance, could you try to run it?  It's supposed to say "ok" six times.
>
>
> On 6/17/20, William Michels <w...@caa.columbia.edu> wrote:
> > Hi Joe,
> >
> > 1. I got your first "if" line (below) from June 14th to work, the one
> > you said, "it's not a complete solution":
> > 1> if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s+/, '\s', :g) }> / {
> >
> > 2. I got Brad's "if" line (below) from June 15th to work:
> > 2> if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / {
> >
> > 3. However, I couldn't get the {}-updated "if" line (below) you posted
> > from June 17th to work:
> > 3> if / (^P\d+) \s+ {} $( %products{$0} ) / {
> >
> > 4. Nor could I get your named-capture "if" line (below) from June 17th to
> > work:
> > 4> if  / $<prod_id>=(^P\d+) \s+
> >             {}
> >             $( %products{$<prod_id>.Str} ) / {
> >
> > By "works", I mean that the third "Corn dogs" example matches, while
> > the first two fail:
> >
> > checking line: P123  Viridian Green Label Saying Magenta
> > NO: bad line.
> > checking line: P666  Yoda puppets
> > NO: bad line.
> > checking line: P912  Corn dogs
> > Matched, line looks good
> >
> > "This is Rakudo version 2020.02.1.0000.1 built on MoarVM version
> > 2020.02.1 implementing Raku 6.d."
> >
> > HTH, Bill.
> >
> >
> >
> > On Wed, Jun 17, 2020 at 1:13 PM Joseph Brenner <doom...@gmail.com> wrote:
> >>
> >> Brad Gilbert <b2gi...@gmail.com> wrote:
> >> > You don't want to use <{…}>, you want to use ""
> >>
> >> >     if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / {
> >>
> >> Well, as contrived examples go this one could be
> >> improved.  Instead of directly dereferencing a
> >> hash, maybe I should've used a sub call.
> >>
> >> > Note that {} is there to update $/ so that $0 works the way you would
> >> > expect
> >>
> >> And notably you really need to know that trick to
> >> get that to work, but the direction I was
> >> going using <{ ... }> just works without it.
> >>
> >> I can confirm that the gratuitous code block trick fixes
> >> the approach I really thought should work:
> >>
> >>    / (^P\d+) \s+ {} $( %products{$0} ) /
> >>
> >> This had me wondering if named captures might work
> >> differently, but they don't, you still need the {}
> >> there:
> >>
> >>    / $<prod_id>=(^P\d+) \s+
> >>             {}
> >>             $( %products{$<prod_id>.Str} ) /
> >>
> >>
> >> > Although I would do something like this instead:
> >> >
> >> >     my ($code,$desc) = $line.split( /\s+/, 2 );
> >> >     if %products{$code} eq $desc {
> >>
> >> Yes, there's other simpler ways... I was just
> >> looking for an excuse to try regex code
> >> interpolation, particularly when using capture
> >> variables in the code... and it does turn out
> >> there's an unexpected (to me) gotcha there.
> >>
> >>
> >> On 6/15/20, Brad Gilbert <b2gi...@gmail.com> wrote:
> >> > You don't want to use <{…}>, you want to use ""
> >> >
> >> >     if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / {
> >> >
> >> > Note that {} is there to update $/ so that $0 works the way you would
> >> > expect
> >> >
> >> > Although I would do something like this instead:
> >> >
> >> >     my ($code,$desc) = $line.split( /\s+/, 2 );
> >> >     if %products{$code} eq $desc {
> >> >
> >> > On Sun, Jun 14, 2020 at 6:44 PM Joseph Brenner <doom...@gmail.com>
> >> > wrote:
> >> >
> >> >> In part because of the recent discussion here, I decided to
> >> >> play around with using Raku code embedded in a regexp.
> >> >> I came up with a contrived example where I was going to
> >> >> examine a product listing in a text block to see if the product
> >> >> descriptions matched the product codes.  The valid associations
> >> >> I have in a hash, so I'm (1) matching for product codes; (2)
> >> >> using embedded code to look-up the associated description in the hash;
> >> >> (3) using the returned description inside the regex.
> >> >>
> >> >> my %products = ( 'P123' => "Green Labels That Say Magenta",
> >> >>                  'P666' => 'Darkseid For President Bumpersticker',
> >> >>                  'P912' => "Corn dogs",
> >> >>                  );
> >> >>
> >> >> my $text =  q:to/END/;
> >> >> P123  Viridian Green Label Saying Magenta
> >> >> P666  Yoda puppets
> >> >> P912  Corn dogs
> >> >> END
> >> >>
> >> >> my @lines = $text.lines;
> >> >> say @lines;
> >> >>
> >> >> for @lines -> $line {
> >> >>    say "checking line: $line";
> >> >>    ## This line works, but it's not a complete solution:
> >> >>    if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s+/, '\s', :g) }>
> >> >> /
> >> >> {
> >> >>        say "Matched, line looks good";
> >> >>    }
> >> >>    else {
> >> >>        say "NO: bad line.";
> >> >>    }
> >> >> }
> >> >>
> >> >> I'd thought that a line like this would work:
> >> >>
> >> >>     if $line ~~ / (^P\d+) \s+ <{ %products{$0} }> / {
> >> >>
> >> >> The trouble though is I've got spaces inside the descriptions,
> >> >> so if the returned string is treated as a regexp, I get these
> >> >> warnings:
> >> >>
> >> >>    Potential difficulties:
> >> >>        Space is not significant here; please use quotes or :s
> >> >> (:sigspace) modifier (or, to suppress this warning, omit the space, or
> >> >> otherwise change the spacing)
> >> >>
> >> >> Reading a bit, I thought this should work
> >> >>
> >> >>     if $line ~~ / (^P\d+) \s+ $( %products{$0} ) / {
> >> >>
> >> >> That's supposed to use the return string as a literal match.
> >> >> Instead I get a lot of strange messages like:
> >> >>
> >> >>    Use of Nil in string context   in regex
> >> >>
> >> >> Flailing around I considered lots of variations like this:
> >> >>
> >> >>    if $line ~~ / (^P\d+) \s+ Q[<{ %products{$0}}>] / {
> >> >>
> >> >> But I think that ends up treating everything inside the Q[]
> >> >> literally, so you never do the hash lookup.
> >> >>
> >> >> Another thing that might solve this problem is some sort of
> >> >> regexp quote function I could use inside the code before
> >> >> returning the string, but I don't know what that would be...
> >> >>
> >> >
> >

Reply via email to