如何获得多子或内置的所有签名?

che*_*nyf 12 perl6 raku

我定义了一个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)
Run Code Online (Sandbox Code Playgroud)

我想得到这个签名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)
Run Code Online (Sandbox Code Playgroud)

但是当我试图获得包含的签名时:

say "a string".^methods.pairs.values[8].value.signature; 
Run Code Online (Sandbox Code Playgroud)

它只输出一个签名:

(Str: | is raw)
Run Code Online (Sandbox Code Playgroud)

在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
Run Code Online (Sandbox Code Playgroud)

这表明该contains方法确实有4个签名!我想知道是否有任何方法可以输出方法/多方法的所有签名

Cur*_*mes 10

尝试 "a string".^lookup('contains').candidates».signature

.^lookup('contains') 会找到的 Method

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


rai*_*iph 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
Run Code Online (Sandbox Code Playgroud)

我已经展示了says 的结果以及它们各自的例程.

如果你调用的foo ...地方foo是多调度例程(与之相同.foo),那么至少在语义上,你实际上是proto在为该名称调用一个声明,然后(通常)重新分配到multi具有相同名称的最佳拟合.如果你打电话给方法&foo那么你就是在protofor 上调用它们foo.

手动声明proto可以完全控制调度过程.它可以制作一杯茶,然后使用Common Lisp调度语义,然后调整结果.或者其他任何想做的事情.

如果multi在未明确声明a proto的情况下声明了一个或多个s,则会proto自动生成默认值.我已手动声明了一个proto显示默认值的内容:

  • 将sig中的;;参数排除在与proto初始发送相关的参数之外;

  • Mu明确地给出了参数列表的整体式通过最广泛的类型(因为如果你不那么指定它的较窄Any的参数);

  • 默认proto接收所有参数(这|是parens所做的);

  • 参数以raw form(is raw)形式接收;

  • 主体调度到下一个相同的命名例程(这就是它的{*} 作用).