Re: interpolating the return from embedded code in a regexp

2020-06-19 Thread William Michels via perl6-users
On Fri, Jun 19, 2020 at 12:12 AM Joseph Brenner  wrote:
>
> > Anyway, I had quite forgotten that you had updated to 2020.05.1 (I thought 
> > you were
> still on 2019.03.1).
>
> I still use the 2019.03 release pretty frequently, but I've got a
> newer release around I can check with.
>
> > FYI, I had been trying to write a line of code that calls the ".words"
> method on both the input lines
>
> Hm.  Something like this?
>
> my $text =  q:to/END/;
> P123  Green Labels That Say Magenta
> P666  Yoda puppets
> P912  Corn dogs
> END
>
> my @lines = $text.lines;
> my @words = $text.words;
>
> say @lines.elems; # 3
> say @words.elems; # 12
>
> say @words[5]; # Magenta

Yes, I tried this line but it failed to match the third product ("Corn dogs"):

#non-working code:
if ($line.words.gist) ~~ m:g/  (^^P\d+) {} <{%products{$0}.words.gist}> /  {

(I see some blog posts showing the use of 'any' and 'all' junctions
with smartmatch operators, so maybe I should have written an 'all'
junction above).

Best, Bill.

>
>
> On 6/18/20, William Michels  wrote:
> > 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: {} "( $0 )"
> > user@mbook:~$ perl6 --version
> > This is Rakudo version 2020.02.1..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  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  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  / $=(^P\d+) \s+
> >> > {}
> >> > $( %products{$.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..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 
> >> > wrote:
> >> >>
> >> >> Brad Gilbert  wrote:
> >> >> > You don't want to use <{…}>, you want to use ""
> >> >>
> >> >> > if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / {
> >> >>
> >> >> Well, as contrived 

Re: interpolating the return from embedded code in a regexp

2020-06-19 Thread Joseph Brenner
> Anyway, I had quite forgotten that you had updated to 2020.05.1 (I thought 
> you were
still on 2019.03.1).

I still use the 2019.03 release pretty frequently, but I've got a
newer release around I can check with.

> FYI, I had been trying to write a line of code that calls the ".words"
method on both the input lines

Hm.  Something like this?

my $text =  q:to/END/;
P123  Green Labels That Say Magenta
P666  Yoda puppets
P912  Corn dogs
END

my @lines = $text.lines;
my @words = $text.words;

say @lines.elems; # 3
say @words.elems; # 12

say @words[5]; # Magenta



On 6/18/20, William Michels  wrote:
> 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: {} "( $0 )"
> user@mbook:~$ perl6 --version
> This is Rakudo version 2020.02.1..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  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  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  / $=(^P\d+) \s+
>> > {}
>> > $( %products{$.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..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 
>> > wrote:
>> >>
>> >> Brad Gilbert  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, 

Re: interpolating the return from embedded code in a regexp

2020-06-18 Thread William Michels via perl6-users
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: {} "( $0 )"
user@mbook:~$ perl6 --version
This is Rakudo version 2020.02.1..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  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  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  / $=(^P\d+) \s+
> > {}
> > $( %products{$.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..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  wrote:
> >>
> >> Brad Gilbert  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:
> >>
> >>/ $=(^P\d+) \s+
> >> {}
> >> $( %products{$.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  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 

Re: interpolating the return from embedded code in a regexp

2020-06-18 Thread Joseph Brenner
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  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  / $=(^P\d+) \s+
> {}
> $( %products{$.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..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  wrote:
>>
>> Brad Gilbert  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:
>>
>>/ $=(^P\d+) \s+
>> {}
>> $( %products{$.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  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 
>> > 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: 

Re: interpolating the return from embedded code in a regexp

2020-06-18 Thread Ralph Mellor
cf:

https://stackoverflow.com/questions/56393888/why-how-is-an-additional-variable-needed-in-matching-repeated-arbitary-character

https://stackoverflow.com/questions/51408141/perl6-grammar-not-sure-about-some-syntax-in-an-example


Re: interpolating the return from embedded code in a regexp

2020-06-18 Thread William Michels via perl6-users
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  / $=(^P\d+) \s+
{}
$( %products{$.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..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  wrote:
>
> Brad Gilbert  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:
>
>/ $=(^P\d+) \s+
> {}
> $( %products{$.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  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  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[]
> >> 

Re: interpolating the return from embedded code in a regexp

2020-06-17 Thread William Michels via perl6-users
Just wondering if the docs describe how to access an "inner" capture
once saved to a variable? If not maybe the code below would be helpful
(from yary's last example, REPL output):

> my $capture = "1122" ~~ /(\d) {} :my $c=$0; ($c (\d) $0)/
「1122」
 0 => 「1」
 1 => 「122」
  0 => 「2」
> say $capture
「1122」
 0 => 「1」
 1 => 「122」
  0 => 「2」
> say ~$capture
1122
> say ~$capture[0]
1
> say ~$capture[1]
122
> say ~$capture[1][0]
2
> say $*VM
moar (2020.02.1)

HTH, Bill.


On Mon, Jun 15, 2020 at 9:42 PM yary  wrote:
>
> Brad: "Note that {} is there to update $/ so that $0 works the way you would 
> expect"
>
> I ran into that before & was trying to remember that detail... found it in 
> https://docs.raku.org/language/regexes#Capture_numbers
>
> But the example is a bit on the obtuse side:
>
> These capture variables are only available outside the regex.
>
> # !!WRONG!! The $0 refers to a capture *inside* the second capture
> say "11" ~~ /(\d) ($0)/; # OUTPUT: «Nil␤»
>
> In order to make them available inside the regex, you need to insert a code 
> block behind the match; this code block may be empty if there's nothing 
> meaningful to do:
>
> # CORRECT: $0 is saved into a variable outside the second capture
> # before it is used inside
> say "11" ~~ /(\d) {} :my $c = $0; ($c)/; # OUTPUT: «「11」␤ 0 => 「1」␤ 1 => 「1」␤»
> say "Matched $c"; # OUTPUT: «␤Matched 1␤»
>
>
> As of Raku 2019.11 at least, the $0 construct works without the {} code 
> block, in simple cases.
>
> > "11" ~~ /(\d) $0/
>
> 「11」
>
>  0 => 「1」
>
> > '876554' ~~ /(\d) $0/
>
> 「55」
>
>  0 => 「5」
>
>
> # Inside a new capture, $0 refers to inner capture
>
> > "11" ~~ /(\d) ($0)/
>
> Nil
>
> > "11" ~~ /(\d) {} ($0)/
>
> Nil
>
> > "11" ~~ /(\d) {} :my $c=$0; ($c)/
>
> 「11」
>
>  0 => 「1」
>
>  1 => 「1」
>
> # Let's use that inner capture
>
> > "1122" ~~ /(\d) {} :my $c=$0; ($c (\d) $0)/
>
> 「1122」
>
>  0 => 「1」
>
>  1 => 「122」
>
>   0 => 「2」
>
>
> The Match docs can be clearer on when to use {} and when it isn't needed, 
> opened an issue https://github.com/Raku/doc/issues/3478
>
> -y
>
>
> On Mon, Jun 15, 2020 at 3:09 PM Brad Gilbert  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  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...


Re: interpolating the return from embedded code in a regexp

2020-06-17 Thread Joseph Brenner
On 6/15/20, yary  wrote:

> The Match docs can be clearer on when to use {} and when it isn't needed,

I agree, in fact I'm inclined to think this is an actual bug (design error?).
It's pretty strange that the two kinds of code interpolation behave so
differently:
$(...) requires you to do something to force capture variables are updated, but
<{...}> doesn't.   Maybe there's a reason you might want to refer to values of
$0 from a previous match, but if so why can't you do it from <{...}>, too?


> opened an issue https://github.com/Raku/doc/issues/3478

Thanks, see you over there.


On 6/15/20, yary  wrote:
> Brad: "Note that {} is there to update $/ so that $0 works the way you
> would expect"
>
> I ran into that before & was trying to remember that detail... found it in
> https://docs.raku.org/language/regexes#Capture_numbers
>
> But the example is a bit on the obtuse side:
>
> These capture variables are only available outside the regex.
>
> # !!WRONG!! The $0 refers to a capture *inside* the second capture
> say "11" ~~ /(\d) ($0)/; # OUTPUT: «Nil␤»
>
> In order to make them available inside the regex, you need to insert a code
> block behind the match; this code block may be empty if there's nothing
> meaningful to do:
>
> # CORRECT: $0 is saved into a variable outside the second capture
> # before it is used inside
> say "11" ~~ /(\d) {} :my $c = $0; ($c)/; # OUTPUT: «「11」␤ 0 => 「1」␤ 1 =>
> 「1」␤»
> say "Matched $c"; # OUTPUT: «␤Matched 1␤»
>
>
> As of Raku 2019.11 at least, the $0 construct works without the {} code
> block, in simple cases.
>
>> "11" ~~ /(\d) $0/
>
> 「11」
>
>  0 => 「1」
>
>> '876554' ~~ /(\d) $0/
>
> 「55」
>
>  0 => 「5」
>
>
> # Inside a new capture, $0 refers to inner capture
>
>> "11" ~~ /(\d) ($0)/
>
> Nil
>
>> "11" ~~ /(\d) {} ($0)/
>
> Nil
>
>> "11" ~~ /(\d) {} :my $c=$0; ($c)/
>
> 「11」
>
>  0 => 「1」
>
>  1 => 「1」
> # Let's use that inner capture
>
>> "1122" ~~ /(\d) {} :my $c=$0; ($c (\d) $0)/
>
> 「1122」
>
>  0 => 「1」
>
>  1 => 「122」
>
>   0 => 「2」
>
> The Match docs can be clearer on when to use {} and when it isn't needed,
> opened an issue https://github.com/Raku/doc/issues/3478
>
> -y
>
>
> On Mon, Jun 15, 2020 at 3:09 PM Brad Gilbert  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  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 

Re: interpolating the return from embedded code in a regexp

2020-06-17 Thread Joseph Brenner
Brad Gilbert  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:

   / $=(^P\d+) \s+
{}
$( %products{$.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  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  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...
>>
>


Re: interpolating the return from embedded code in a regexp

2020-06-15 Thread yary
Brad: "Note that {} is there to update $/ so that $0 works the way you
would expect"

I ran into that before & was trying to remember that detail... found it in
https://docs.raku.org/language/regexes#Capture_numbers

But the example is a bit on the obtuse side:

These capture variables are only available outside the regex.

# !!WRONG!! The $0 refers to a capture *inside* the second capture
say "11" ~~ /(\d) ($0)/; # OUTPUT: «Nil␤»

In order to make them available inside the regex, you need to insert a code
block behind the match; this code block may be empty if there's nothing
meaningful to do:

# CORRECT: $0 is saved into a variable outside the second capture
# before it is used inside
say "11" ~~ /(\d) {} :my $c = $0; ($c)/; # OUTPUT: «「11」␤ 0 => 「1」␤ 1 => 「1」␤»
say "Matched $c"; # OUTPUT: «␤Matched 1␤»


As of Raku 2019.11 at least, the $0 construct works without the {} code
block, in simple cases.

> "11" ~~ /(\d) $0/

「11」

 0 => 「1」

> '876554' ~~ /(\d) $0/

「55」

 0 => 「5」


# Inside a new capture, $0 refers to inner capture

> "11" ~~ /(\d) ($0)/

Nil

> "11" ~~ /(\d) {} ($0)/

Nil

> "11" ~~ /(\d) {} :my $c=$0; ($c)/

「11」

 0 => 「1」

 1 => 「1」
# Let's use that inner capture

> "1122" ~~ /(\d) {} :my $c=$0; ($c (\d) $0)/

「1122」

 0 => 「1」

 1 => 「122」

  0 => 「2」

The Match docs can be clearer on when to use {} and when it isn't needed,
opened an issue https://github.com/Raku/doc/issues/3478

-y


On Mon, Jun 15, 2020 at 3:09 PM Brad Gilbert  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  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...
>>
>


Re: interpolating the return from embedded code in a regexp

2020-06-15 Thread Brad Gilbert
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  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...
>


Re: interpolating the return from embedded code in a regexp

2020-06-14 Thread yary
True, and I am well and truly baffled by my example where the 1st bad line
incorrectly is labelled good, the 2nd bad line is correctly labelled bad,
and the 3rd good like is correctly labelled good.

-y


On Sun, Jun 14, 2020 at 6:04 PM Joseph Brenner  wrote:

> > Just to be be clear, my idea is the second line is wrong, and it
> should flag that one as a problem
>
> Oh, but if you go literally with the code I posted, *both* the first
> and second lines have incorrect descriptions, and only the third line
> ("corn dogs") matches.
>
> (That was a mistake when I wrote it up, but whatever.)
>
>
>
> On 6/14/20, Joseph Brenner  wrote:
> > Well, with the first one it rejects all of my lines, and with the
> > second one it passes all of them.
> >
> > Just to be be clear, my idea is the second line is wrong, and it
> > should flag that one as a problem
> >
> >
> >
> > On 6/14/20, yary  wrote:
> >> https://docs.raku.org/language/regexes#Regex_interpolation gave me some
> >> ideas
> >>
> >> Try matching against  / (^P\d+) \s+ %products{$0} /
> >>
> >> This one also works, in a roundabout way
> >>  / (^P\d+) \s+ {"%products{$0}"} /
> >> -y
> >>
> >>
> >> On Sun, Jun 14, 2020 at 4:44 PM Joseph Brenner 
> 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...
> >>>
> >>
> >
>


Re: interpolating the return from embedded code in a regexp

2020-06-14 Thread Joseph Brenner
> Just to be be clear, my idea is the second line is wrong, and it
should flag that one as a problem

Oh, but if you go literally with the code I posted, *both* the first
and second lines have incorrect descriptions, and only the third line
("corn dogs") matches.

(That was a mistake when I wrote it up, but whatever.)



On 6/14/20, Joseph Brenner  wrote:
> Well, with the first one it rejects all of my lines, and with the
> second one it passes all of them.
>
> Just to be be clear, my idea is the second line is wrong, and it
> should flag that one as a problem
>
>
>
> On 6/14/20, yary  wrote:
>> https://docs.raku.org/language/regexes#Regex_interpolation gave me some
>> ideas
>>
>> Try matching against  / (^P\d+) \s+ %products{$0} /
>>
>> This one also works, in a roundabout way
>>  / (^P\d+) \s+ {"%products{$0}"} /
>> -y
>>
>>
>> On Sun, Jun 14, 2020 at 4:44 PM Joseph Brenner  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...
>>>
>>
>


Re: interpolating the return from embedded code in a regexp

2020-06-14 Thread Joseph Brenner
Getting correct behavior is an improvement over my try like so, which
gets the same warning but fails all the lines:

   / (^P\d+) \s+ $(%products{$0}) /

On 6/14/20, yary  wrote:
> I should have read the output!
>
> This one gives the right answers but with lots of warnings
> / (^P\d+) \s+ $("%products{$0}") /
>
> checking line: P123  Viridian Green Label Saying Magenta
>
> Use of Nil in string context
>
>   in regex  at regex-loop.p6 line 18
>
> Use of Nil in string context
>
>   in regex  at regex-loop.p6 line 18
>
> Use of uninitialized value %products{''} of type Any in string context.
>
> Methods .^name, .perl, .gist, or .say can be used to stringify it to
> something meaningful.
>
>   in regex  at regex-loop.p6 line 18
>
> Matched, line looks good
>
> checking line: P666  Yoda puppets
>
> NO: bad line.
> ...
> Why is it reading with an empty-string $0 in %products{''}
>
> -y
>
>
> On Sun, Jun 14, 2020 at 5:47 PM Joseph Brenner  wrote:
>
>> Well, with the first one it rejects all of my lines, and with the
>> second one it passes all of them.
>>
>> Just to be be clear, my idea is the second line is wrong, and it
>> should flag that one as a problem
>>
>>
>>
>> On 6/14/20, yary  wrote:
>> > https://docs.raku.org/language/regexes#Regex_interpolation gave me some
>> > ideas
>> >
>> > Try matching against  / (^P\d+) \s+ %products{$0} /
>> >
>> > This one also works, in a roundabout way
>> >  / (^P\d+) \s+ {"%products{$0}"} /
>> > -y
>> >
>> >
>> > On Sun, Jun 14, 2020 at 4:44 PM Joseph Brenner 
>> 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...
>> >>
>> >
>>
>


Re: interpolating the return from embedded code in a regexp

2020-06-14 Thread yary
I should have read the output!

This one gives the right answers but with lots of warnings
/ (^P\d+) \s+ $("%products{$0}") /

checking line: P123  Viridian Green Label Saying Magenta

Use of Nil in string context

  in regex  at regex-loop.p6 line 18

Use of Nil in string context

  in regex  at regex-loop.p6 line 18

Use of uninitialized value %products{''} of type Any in string context.

Methods .^name, .perl, .gist, or .say can be used to stringify it to
something meaningful.

  in regex  at regex-loop.p6 line 18

Matched, line looks good

checking line: P666  Yoda puppets

NO: bad line.
...
Why is it reading with an empty-string $0 in %products{''}

-y


On Sun, Jun 14, 2020 at 5:47 PM Joseph Brenner  wrote:

> Well, with the first one it rejects all of my lines, and with the
> second one it passes all of them.
>
> Just to be be clear, my idea is the second line is wrong, and it
> should flag that one as a problem
>
>
>
> On 6/14/20, yary  wrote:
> > https://docs.raku.org/language/regexes#Regex_interpolation gave me some
> > ideas
> >
> > Try matching against  / (^P\d+) \s+ %products{$0} /
> >
> > This one also works, in a roundabout way
> >  / (^P\d+) \s+ {"%products{$0}"} /
> > -y
> >
> >
> > On Sun, Jun 14, 2020 at 4:44 PM Joseph Brenner 
> 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...
> >>
> >
>


Re: interpolating the return from embedded code in a regexp

2020-06-14 Thread Joseph Brenner
Well, with the first one it rejects all of my lines, and with the
second one it passes all of them.

Just to be be clear, my idea is the second line is wrong, and it
should flag that one as a problem



On 6/14/20, yary  wrote:
> https://docs.raku.org/language/regexes#Regex_interpolation gave me some
> ideas
>
> Try matching against  / (^P\d+) \s+ %products{$0} /
>
> This one also works, in a roundabout way
>  / (^P\d+) \s+ {"%products{$0}"} /
> -y
>
>
> On Sun, Jun 14, 2020 at 4:44 PM Joseph Brenner  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...
>>
>


Re: interpolating the return from embedded code in a regexp

2020-06-14 Thread yary
https://docs.raku.org/language/regexes#Regex_interpolation gave me some
ideas

Try matching against  / (^P\d+) \s+ %products{$0} /

This one also works, in a roundabout way
 / (^P\d+) \s+ {"%products{$0}"} /
-y


On Sun, Jun 14, 2020 at 4:44 PM Joseph Brenner  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...
>


interpolating the return from embedded code in a regexp

2020-06-14 Thread Joseph Brenner
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...