Perl 6 多方法永远不会匹配预期的签名
Perl 6 multi methods never match expected signature
我有一个 class 有两个 multi 方法 (multi submit
)。
我这样称呼我的 multi:
$perspective.submit(:message($message.content));
哪个被运到我的 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>;
}
但是我总是得到以下响应:
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
声明了默认值。
分两个阶段进行多次调度:
- 考虑位置参数的数量及其类型
- 如果有任何
where
子句、命名参数或 sub-signatures,请对签名进行测试绑定以查看它是否匹配
如果由于任何原因未能绑定,第二阶段将拒绝候选人。其中一个原因,我相信这里的问题的原因,是默认值输入错误。例如,在:
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)) {
应该可以。
我看到两个问题。
一个是你有两个除了一个命名参数的名称之外完全相同的方法。
命名参数可以有别名:
# 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)
的缩写
现在讨论实际上阻止您的代码工作的问题。
@models
是 Positional,但您在签名中为其分配了一个奇异值。
给它分配一个位置,它起作用了:
(在这种情况下,由于 MODEL
类型声明,它必须是 Array[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>;
}
我有一个 class 有两个 multi 方法 (multi submit
)。
我这样称呼我的 multi:
$perspective.submit(:message($message.content));
哪个被运到我的 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>;
}
但是我总是得到以下响应:
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
声明了默认值。
分两个阶段进行多次调度:
- 考虑位置参数的数量及其类型
- 如果有任何
where
子句、命名参数或 sub-signatures,请对签名进行测试绑定以查看它是否匹配
如果由于任何原因未能绑定,第二阶段将拒绝候选人。其中一个原因,我相信这里的问题的原因,是默认值输入错误。例如,在:
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)) {
应该可以。
我看到两个问题。
一个是你有两个除了一个命名参数的名称之外完全相同的方法。
命名参数可以有别名:
# 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)
现在讨论实际上阻止您的代码工作的问题。
@models
是 Positional,但您在签名中为其分配了一个奇异值。
给它分配一个位置,它起作用了:
(在这种情况下,由于 MODEL
类型声明,它必须是 Array[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>;
}