如何正确扩充Any?

时间:2018-10-09 10:11:52

标签: perl6

以下程序:

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

是错误还是我只是认为错误?

2 个答案:

答案 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)