> my @numbers = 1, 3, 5;
> 1 ~~ /@numbers/; #
「1」
is the same as:
> 1 ~~ /1 | 3 | 5/
「1」
but when the element is a Range object, it fails to match:
> my @ranges = 1..3.item, 4..6.item;
[1..3 4..6]
> 1 ~~ /@ranges/
Nil
> 1 ~~ /|@ranges/
Nil
> 1 ~~ /||@ranges/
When the regex engine sees /@numbers/
it treats that like an alternation of the array elements, so your first two examples are equivalent.
There just is no such automatism for Range
s I believe.
Edit: Never mind below, I totally misread the question at first.
> my @ranges = 1..3, 4..6;
[1..3 4..6]
> 1 ~~ @ranges[0];
True
> 2 ~~ @ranges[1];
False
> 4 ~~ @ranges[1];
True
> @ranges.first( 5 ~~ * )
4..6
See? @ranges
is a array of, well, ranges (your call to item
does nothing here). Theoretically this would hold true if the smartmatch operator were smarter.
> 1..3 ~~ @ranges;
False
Flattening also doesn't help, because a flat list of ranges is still a list of ranges.
Flattening the ranges themselves is possible, but that simply turns them into Arrays
> my @ranges2 = |(1..3), |(4..6)
[1 2 3 4 5 6]
Why does single number fails to match Range object in array?
Per the doc:
The interpolation rules for individual elements [of an array] are the same as for scalars
And per the same doc section the rule for a scalar (that is not a regex) is:
interpolate the stringified value
A range object such as 1..3
stringifies to 1 2 3
:
my $range = 1..3;
put $range; # 1 2 3
put so '1' ~~ / $range /; # False
put so '1 2 3' ~~ / $range /; # True
So, as Holli suggests, perhaps instead:
my @ranges = flat 1..3, 4..6;
say @ranges; # [1 2 3 4 5 6]
say 1 ~~ /@ranges/; # 「1」
Or is there some reason you don't want that? (See also Scimon's comment on Holli's answer.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With