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