以下程序:
use v6.c;
use MONKEY-TYPING;
augment class Any {
method show0 { self.say }}
augment class List {
method show1 { self.say }}
<hello world>.show0;
<hello world>.show1;
产生预期的输出:
(hello world)
(hello world)
与此同时:
use v6.c;
use MONKEY-TYPING;
augment class Any {
method show0 { self.say }}
<hello world>.show0;
产生错误:
No such method 'show0' for invocant of type 'List'. Did you mean 'show0'?
in block <unit> at showcase.p6 line 9
是错误还是我只是认为错误?
答案 0 :(得分:9)
首先:至少在Rakudo Perl 6可以预见的未来,增强核心类不是一个好主意。预编译效果不佳。
第二:当一个类是另一个类的子类时,子类“知道”它所继承的子类。 las,这反过来没有用:一个类(至少在撰写本文时)不知道其子类。
这意味着,如果您扩充Any
,则它的所有子类都不知道也应该重新构成自己。在第一个示例中,您可以通过扩展List
类来实现这一点。但是,如果您要颠倒增强的顺序,那么也将不起作用,因为List
类将在Any
类被重新构成之前被重新构成。
因此,建议将使用角色的所有其他方法混合到类或对象(mixins of roles中)
答案 1 :(得分:2)
此处以及我在Github上创建的问题的各种评论的摘要:
正如Liz提到的那样,目前孩子类型的父母没有增加。除非刷新了该类型的方法缓存,否则都是如此。
此行为是已知的限制,将来会以较低的优先级修复。
使用.^compose
重建类可以使孩子知道增强方法:
use v6.c;
use MONKEY-TYPING;
augment class Any {
method show0 { self.say }}
List.^compose;
<hello world>.show0; # OUTPUT: (hello world)
或者可以直接访问合格的类:
use v6.c;
use MONKEY-TYPING;
augment class Any {
method show0 { self.say }}
<hello world>.Any::show0; # OUTPUT: (hello world)