Theoretically, ~~ is syntactic sugar for ACCEPTS
so the last two lines should return the same value:
my %myth-objects = %(Þor => "Mjólnir", Oðinn => "Hugin") ;
say %myth-objects;
say %myth-objects.ACCEPTS("Oðinn");
say %myth-objects ~~ "Oðinn";
However, the first returns True
and the second returns False
. What am I missing here?
There are two problems with what you have.
Smartmatch has two execution layers.
one is immediate
'abc' ~~ $_ eq 'XYZ'
.ACCEPTS
is then called on the result, with the given value as the argument
do given 'abc' { ($_ eq 'XYZ').ACCEPTS($_) }
# ^ ^
# | |
# +------- 'abc'-------+
In the above case $_ eq 'XYZ'
is False
, and False.ACCEPTS(|)
always returns False
.
(Similarly True.ACCEPTS(|)
always returns True
.)
You could also return a Callable.
'abc' ~~ * eq 'XYZ'
This will appear to have the effect of removing the first immediate layer.
(It doesn't actually do that though.)
do given 'abc' { (* eq 'XYZ').ACCEPTS($_) }
do given 'abc' { (* eq 'XYZ').($_) }
do given 'abc' { $_ eq 'XYZ' }
Or it could return a type or literal.
'abc' ~~ ( 1 ?? Str !! Int ) # 'abc' ~~ Str
do given 'abc' { ( 1 ?? Str !! Int ).ACCEPTS($_) }
do given 'abc' { ( Str ).ACCEPTS($_) }
Str .ACCEPTS('abc')
You have the left hand side, and the right hand side swapped.
These two lines are similar.
(Ignoring that there are really two execution layers.)
'abc' ~~ 'XYZ'
'XYZ'.ACCEPTS('abc')
The important point to remember is that the right side of ~~
gets to decide how the smartmatch happens. The only way that can happen is if the method call was on it, not the left side.
(Note that all of the above also applies to when
and where
clauses. because they are also smartmatch features.)
So of course these have different results.
%myth-objects.ACCEPTS("Oðinn")
%myth-objects ~~ "Oðinn"
These three are similar.
%myth-objects ~~ "Oðinn"
do given %myth-objects { "Oðinn".ACCEPTS($_) } # identical
"Oðinn".ACCEPTS(%myth-objects) # simplified
As are these
%myth-objects.ACCEPTS("Oðinn")
do given "Oðinn" { %myth-objects.ACCEPTS($_) } # expanded to two layers
"Oðinn" ~~ %myth-objects # smartmatched
Is it not the other way:
say 'Oðinn' ~~ %myth-objects;
According to the doc: The smartmatch operator aliases the left-hand side to $_ , then evaluates the right-hand side and calls .ACCEPTS($_) on it.
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