Perl 6 multi methods never match expected signature
I see two issues.
One is that you have two methods that are identical except for the name of one named parameter.
Named parameters can have aliases:
# V--------------V
multi method submit(Str :name(:$message)!, MODEL :@models = TOXICITY) {
my $score = $perspective-api.analyze(:@models, :comment($message));
say @models Z=> $score<attributeScores>{@models}.map: *<summaryScore><value>;
}
Note that :$message
is really short for :message($message)
Now on the problem which actually prevents your code from working.
@models
is a Positional, but you are assigning it a singular value in the signature.
Assign it a Positional, and it works:
(In this case it has to be of type Array[MODEL]
because of the MODEL
type declaration.)
# V---------------------V
multi method submit(Str :name(:$message)!, MODEL :@models = Array[MODEL](TOXICITY,)) {
my $score = $perspective-api.analyze(:@models, :comment($message));
say @models Z=> $score<attributeScores>{@models}.map: *<summaryScore><value>;
}
Multiple dispatch works in two phases:
- Considering the number of positional parameters and their types
- If there are any
where
clauses, named parameters, or sub-signatures, doing a test bind of the signature to see if it would match
The second phase will reject the candidate if it fails to bind for any reason. One such reason, and I believe the cause of the issue here, is that the default value is wrongly typed. For example, in:
multi m(:@x = "not-an-array") { }
m()
We get an error:
Cannot resolve caller m(...); none of these signatures match:
(:@x = "not-an-array")
in block <unit> at -e line 1
But changing it to:
multi m(:@x = ["an-array"]) { }
m()
Works fine. (Note that while a default value uses =
, it's actually a binding, not an assignment.)
In the case in the question there's this:
MODEL :@models = TOXICITY
Looking at the module source the code is taken from, I see:
enum MODEL is export (
<TOXICITY SEVERE_TOXICITY TOXICITY_FAST IDENTITY_ATTACK
INSULT PROFANITY SEXUALLY_EXPLICIT THREAT FLIRTATION
ATTACK_ON_AUTHOR ATTACK_ON_COMMENTER INCOHERENT INFLAMMATORY
LIKELY_TO_REJECT OBSCENE SPAM UNSUBSTANTIAL>
);
Thus TOXICITY is just an Int
, but what's expected is a typed array of MODEL
values.
Thus, if you do this:
multi method submit(Str :$message!, MODEL :@models = Array[MODEL](TOXICITY)) {
It should work.