I have a class with two multi methods (multi submit
).
I call my multi like this:
$perspective.submit(:message($message.content));
Which gets shipped off to my class:
my $perspective-api = API::Perspective.new(:api-key(%*ENV<PERSPECTIVE_API_KEY>));
proto method submit (|) {*}
multi method submit(Str :$message!, MODEL :@models = TOXICITY) {
my $score = $perspective-api.analyze(:@models, :comment($message));
say @models Z=> $score<attributeScores>{@models}.map: *<summaryScore><value>;
multi method submit(Str :$name!, MODEL :@models = TOXICITY) {
my $score = $perspective-api.analyze(:@models, :comment($name));
say @models Z=> $score<attributeScores>{@models}.map: *<summaryScore><value>;
}
However I always get the following response:
Died because of the exception:
Cannot resolve caller AUTOGEN(Rose::ContentAnalysis::Perspective:D: :message(Str)); none of these signatures match:
(Rose::ContentAnalysis::Perspective: Str :$message!, MODEL :@models = MODEL::TOXICITY, *%_)
(Rose::ContentAnalysis::Perspective: Str :$name!, MODEL :@models = MODEL::TOXICITY, *%_)
Despite my named argument (:message
) being a Str
as required and @models
having a default declared.
Multiple dispatch works in two phases:
where
clauses, named parameters, or sub-signatures, doing a test bind of the signature to see if it would matchThe 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.
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