ACCEPTS vs smartmatch in Hashes: what's the difference?

There are two problems with what you have.

  1. 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')
    
  2. 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.

Tags:

Raku