就目前而言multi
methods
,这与在同一个模块或文件中根本没有关系。考虑这些类:
class Base {
proto method m(|) { * }
multi method m() { 1 }
}
class Derived is Base {
multi method m() { 2 }
}
每当我们编写一个包含多个方法的类时,我们都需要将它们附加到一个控件上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;
然后输出是:
Base:
multi method m (Base: *%_) { #`(Method|82762064) ... }
Derived:
multi method m (Base: ) { #`(Method|82762064) ... }
multi method m (Derived: ) { #`(Method|82762208) ... }
也就是说,候选列表中Base
有一个条目,并且候选列表中Derived
的条目具有克隆的条目Base
以及新条目。
几乎所有东西都遵循这个原则:派生类引用它们的基类(以及它们所做的角色),但基类(和角色)不知道它们的后代。