cod*_*ons 7 documentation introspection rakudo raku
当 proto 和 multis 在同一个模块中定义时,Type.^lookup('method').candidates返回所有多候选者的列表。但是,当 proto 与 multis 位于不同的文件/模块中时,这似乎不起作用。
say Setty.^lookup('grab').candidates; # OUTPUT: ()
Run Code Online (Sandbox Code Playgroud)
有没有办法通过Raku的自省找到完整的多候选人名单?或者除了搜索源代码之外别无选择?(我问是因为拥有适用于给定 proto 的多候选者的完整列表将有助于文档目的。)
到目前为止multi methods,这与在同一个模块或文件中完全没有关系。考虑这些类:
class Base {
proto method m(|) { * }
multi method m() { 1 }
}
class Derived is Base {
multi method m() { 2 }
}
Run Code Online (Sandbox Code Playgroud)
每当我们组合一个包含多个方法的类时,我们需要将它们附加到一个控制proto. 在 的情况下Base,这是明确编写的,因此除了将multi候选人添加到其候选人列表之外别无他法。但是,如果我们没有proto明确地在 中写入Base,那么将为我们生成一个具有空候选列表的列表,并具有相同的最终结果。
然而,我刚刚描述的过程稍微简化了实际发生的情况。步骤是:
proto已经有了;如果是这样,添加multi到它proto; 如果是这样,请克隆它(在 tern 中克隆候选列表)并将其添加multi到该列表中。proto.第 2 步确实是您问题的答案。如果我们这样做:
say "Base:";
.raku.say for Base.^lookup('m').candidates;
say "Derived:";
.raku.say for Derived.^lookup('m').candidates;
Run Code Online (Sandbox Code Playgroud)
然后输出是:
Base:
multi method m (Base: *%_) { #`(Method|82762064) ... }
Derived:
multi method m (Base: ) { #`(Method|82762064) ... }
multi method m (Derived: ) { #`(Method|82762208) ... }
Run Code Online (Sandbox Code Playgroud)
也就是说,候选列表 inBase有一个条目,候选列表 inDerived具有克隆的条目Base和新条目。
几乎所有的东西都遵循这个原则:派生类引用它们的基类(和它们扮演的角色),但基类(和角色)不知道它们的后代。