10

我有一个有两个多方法(multi submit)的类。

我这样称呼我的多:

$perspective.submit(:message($message.content));

哪个被运到我的班级:

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>;
}

但是我总是得到以下回复:

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, *%_)

尽管我的命名参数 ( :message) 是Str必需的并且@models声明了默认值。

4

2 回答 2

12

多分派分两个阶段工作:

  • 考虑位置参数的数量及其类型
  • 如果有任何where子句、命名参数或子签名,则对签名进行测试绑定以查看它是否匹配

如果候选人因任何原因未能绑定,第二阶段将拒绝该候选人。一个这样的原因,我相信这里问题的原因是默认值输入错误。例如,在:

multi m(:@x = "not-an-array") { }
m()

我们得到一个错误:

Cannot resolve caller m(...); none of these signatures match:
    (:@x = "not-an-array")
  in block <unit> at -e line 1

但将其更改为:

multi m(:@x = ["an-array"]) { }
m()

工作正常。(请注意,虽然默认值使用=,但它实际上是一个绑定,而不是一个赋值。)

在问题的情况下,有这样的:

MODEL :@models = TOXICITY

查看代码的模块源代码,我看到:

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>
);

因此 TOXICITY 只是一个Int,但预期的是一个类型化的MODEL值数组。

因此,如果您这样做:

multi method submit(Str :$message!, MODEL :@models = Array[MODEL](TOXICITY)) {

它应该工作。

于 2019-06-25T16:01:51.857 回答
8

我看到两个问题。

一种是您有两种相同的方法,除了一个命名参数的名称。

命名参数可以有别名:

#                       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>;
}

请注意,这:$message真的很短:message($message)


现在讨论实际上阻止您的代码工作的问题。

@modelsPositional,但您在签名中为其分配了一个奇异值。

为它分配一个Positional,它就可以工作了:(在这种情况下,由于类型声明
,它必须是类型的。)Array[MODEL]MODEL

#                                                           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>;
}
于 2019-06-25T16:02:52.550 回答