Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl6 How to use adverbs as variables?

Tags:

I am trying to match a string either case-sensitive or case-insensitive. Is there a way to make the .match method take adverbs as variables?

my $aString = "foo bar baz";
my @anArray = <OO AR AZ>;
my $anAdverb = :i;
my $firstCheck = ($aString.match(/$anAdverb "@anArray[0]" /)).Bool;

Using $anAdverb inside the regex does not work. Is there a work-around?

like image 416
lisprogtor Avatar asked Dec 20 '16 20:12

lisprogtor


1 Answers

In expression context (i.e. outside of argument lists), :foo creates a Pair object.
This object can then be interpolated as an adverb into an argument list, using |:

my $adverb = :g;
say "a 1 b 2".match(/\d/, |$adverb);

Unfortunately, the .match method does not support the :i adverb. (Arguably an oversight - maybe open a Rakudo bug report.)

I don't think there's a way to interpolate an adverb into a regex.

You could store your regex as a string, and and use the <$foo> syntax to eval it at runtime into one of two different "wrapper" regexes (one with :i, and one without):

use MONKEY-SEE-NO-EVAL;

my $string = "foo bar baz";
my @array = <OO AR AZ>;
my $case-sensitive = True;
my $regex = ' "@array[0]" ';

say ?$string.match($case-sensitive ?? /:i <$regex>/ !! /<$regex>/);

However, this is unsafe if any user-provided data ends up in the regex.

Of course, if the whole regex just matches a literal substring, there's no need for eval and you can safely interpolate the substring into the wrapper regexes like this:

my $string = "foo bar baz";
my @array = <OO AR AZ>;
my $case-sensitive = True;
my $substring = @array[0];

say ?$string.match($case-sensitive ?? /:i $substring/ !! /$substring/);
like image 123
smls Avatar answered Sep 24 '22 16:09

smls