Raku 的自省能否列出所有跨越 files/Modules 的多个候选人?
Can Raku's introspection list all the multi candidates across different files/Modules?
当在同一个模块中定义了 proto 和 multis 时,Type.^lookup('method').candidates
returns 所有 multi 候选项的列表。但是,当 proto 与 multis 处于不同的 file/module 时,这似乎不起作用。
say Setty.^lookup('grab').candidates; # OUTPUT: ()
有没有办法通过Raku的内省找到完整的多候选名单?或者除了 grepping 源代码之外别无选择? (我问是因为拥有适用于给定原型的多个候选人的完整列表将是 helpful for documentation purposes。)
就 multi
methods
而言,这与位于同一模块或文件中根本无关。考虑这些 classes:
class Base {
proto method m(|) { * }
multi method m() { 1 }
}
class Derived is Base {
multi method m() { 2 }
}
每当我们编写包含多个方法的 class 时,我们需要将它们附加到控制 proto
。在 Base
的情况下,这是明确写入的,因此除了将 multi
候选者添加到其候选者列表之外别无他法。然而,如果我们没有在 Base
中明确地写一个 proto
,那么就会为我们生成一个空的候选列表,最终结果相同。
不过,我刚才描述的过程只是对实际发生的事情进行了一些简化。步骤是:
- 看看这个 class 是否已经有一个
proto
;如果是这样,请将 multi
添加到其中
- 否则,查看是否有任何碱基 class 具有
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
克隆的条目以及一个新的条目。
几乎所有的东西都遵循这个原则:派生的 classes 引用他们的基础 class(以及他们所做的角色),但是基础 classes(和角色)不知道他们的后代。
当在同一个模块中定义了 proto 和 multis 时,Type.^lookup('method').candidates
returns 所有 multi 候选项的列表。但是,当 proto 与 multis 处于不同的 file/module 时,这似乎不起作用。
say Setty.^lookup('grab').candidates; # OUTPUT: ()
有没有办法通过Raku的内省找到完整的多候选名单?或者除了 grepping 源代码之外别无选择? (我问是因为拥有适用于给定原型的多个候选人的完整列表将是 helpful for documentation purposes。)
就 multi
methods
而言,这与位于同一模块或文件中根本无关。考虑这些 classes:
class Base {
proto method m(|) { * }
multi method m() { 1 }
}
class Derived is Base {
multi method m() { 2 }
}
每当我们编写包含多个方法的 class 时,我们需要将它们附加到控制 proto
。在 Base
的情况下,这是明确写入的,因此除了将 multi
候选者添加到其候选者列表之外别无他法。然而,如果我们没有在 Base
中明确地写一个 proto
,那么就会为我们生成一个空的候选列表,最终结果相同。
不过,我刚才描述的过程只是对实际发生的事情进行了一些简化。步骤是:
- 看看这个 class 是否已经有一个
proto
;如果是这样,请将multi
添加到其中 - 否则,查看是否有任何碱基 class 具有
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
克隆的条目以及一个新的条目。
几乎所有的东西都遵循这个原则:派生的 classes 引用他们的基础 class(以及他们所做的角色),但是基础 classes(和角色)不知道他们的后代。