我定义了一个具有两个签名的multi sub
:
multi sub mie(Str $s, Int $i) { $s x $i }
multi sub mie(Int $s, Int $i) { ... }
say &mie.signature; # ;; Mu | is raw)
我想获得此multi sub
的签名,但以上结果并非我所期望的。
如文档所述,contains是具有4个签名的多重方法:
multi method contains(Str:D: Cool:D $needle)
multi method contains(Str:D: Str:D $needle)
multi method contains(Str:D: Cool:D $needle, Int(Cool:D) $pos)
multi method contains(Str:D: Str:D $needle, Int:D $pos)
但是当我尝试获取contains的签名时:
say "a string".^methods.pairs.values[8].value.signature;
仅输出一个签名:
(Str: | is raw)
在REPL中,当我不带任何参数调用contains
方法时,它会输出以下错误:
> "a string".contains()
Cannot resolve caller contains(Str: ); none of these signatures match:
(Str:D: Cool:D $needle, *%_)
(Str:D: Str:D $needle, *%_)
(Str:D: Cool:D $needle, Cool:D $pos, *%_)
(Str:D: Str:D $needle, Int:D $pos, *%_)
in block <unit> at <unknown file> line 1
这表明contains
方法确实具有4个签名!我想知道是否有任何方法可以输出方法/多方法的所有signature?
答案 0 :(得分:10)
尝试"a string".^lookup('contains').candidates».signature
.^lookup('contains')
将找到Method
.candidates
将列出多个candidates
.signature
将为您每个人提供Signature
。
输出:
((Str:D: Cool:D $needle, *%_) (Str:D: Str:D $needle, *%_) (Str:D: Cool:D $needle, Cool:D $pos, *%_) (Str:D: Str:D $needle, Int:D $pos, *%_))
您也可以将其用于multi sub
:
say &mie.candidates».signature;
答案 1 :(得分:9)
作为Curt回答的补充:
proto foo (;; Mu | is raw) {*} # proto(;; Mu | is raw)
multi foo ($a) { } # multi($a)
multi foo (Int $a) { } # multi(Int $a)
multi foo ($a,$b) { } # multi($a, $b)
multi foo (Int $a,$b) { } # multi(Int $a, $b)
say 'proto', .signature for &foo; # displays 1 line
say 'multi', .signature for &foo.candidates; # displays 4 lines
我已经展示了say
的结果以及它们各自的例程。
如果您调用foo ...
,其中foo
是一个多重调度例程(与.foo
相同),那么至少在语义上,您实际上是在为{然后(通常)使用相同的名称重新分配为最合适的multi
的名称。如果您在&foo
上调用方法,那么您将在proto
的{{1}}上调用它们。
手动声明的foo
提供了对分发过程的完全控制。它可以泡一杯茶,然后使用Common Lisp调度语义,然后对结果进行修饰。或它想做的其他事情。
如果在未显式声明proto
的情况下声明了一个或多个multi
,则会自动生成默认的proto
。我已经手动声明了一个proto
来显示默认值:
proto
将proto
sig中的参数与初始分配无关;
proto
显式地给出了传递的参数列表的整体类型,该类型是最广泛的类型(因为如果您未指定,则参数的缩窄Mu
);
默认的Any
接收所有参数(这是括号中的proto
所做的事情);
以原始格式(|
)接收参数;
主体将分派到下一个相同的命名例程(is raw
就是这样做的。)
答案 2 :(得分:1)
为此我制作了P6Repl::Helper
模块。