如何获取多子或内置插件的所有签名?

时间:2018-09-26 10:20:49

标签: 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)

我想获得此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

3 个答案:

答案 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来显示默认值:

  • protoproto sig中的参数与初始分配无关;

  • proto显式地给出了传递的参数列表的整体类型,该类型是最广泛的类型(因为如果您未指定,则参数的缩窄Mu);

  • 默认的Any接收所有参数(这是括号中的proto所做的事情);

  • 以原始格式(|)接收参数;

  • 主体将分派到下一个相同的命名例程(is raw就是这样做的。)

答案 2 :(得分:1)

为此我制作了P6Repl::Helper模块。