如何删除 Raku 中的多方法

How to remove a multi method in Raku

如何使用将在已定义方法之前调用的多重方法来扩充 class?

我正在尝试启用负下标:@arr[-1] 就像 this 文章中那样,但不更改源代码。

所以我增加了Array

augment class Array { 
    proto method AT-POS(Array:D: Int:D $i where <0 ) {
        say "AT-POS called";
        my $pos = -1;
        my $ix = $pos + self.elems;
        return self.AT-POS($ix);
    }
};

但正如 doc

中所述
Please note that adding a multi candidate that differs only
in its named parameters will add that candidate behind the already defined one
and as such it won't be picked by the dispatcher.

所以我的 multi 从未被调用过:

say .signature for @arr.^method_table{'AT-POS'}.candidates ;
(Any:U \SELF: int \pos, *%_)
(Any:U \SELF: Int:D \pos, *%_)
(Any:U: Num:D \pos, *%_)
(Any:U: Any:D \pos, *%_)
(Any:D: int \pos, *%_)
(Any:D: Int:D \pos, *%_)
(Any:D: Num:D \pos, *%_)
(Any:D: Any:D \pos, *%_)
($: Any:U \pos, *%_)
(Any:D: \one, \two, *%_)
(Any:D: \one, \two, \three, *%_)
(Any:D: **@indices, *%_)
(List:D: int $pos, *%_)
(List:D: Int:D $pos, *%_)
(Array:D: int $pos, *%_)
(Array:D: Int:D $pos, *%_)  # Their
(Array: $a, *%_)
(Array:D: Int:D $pos, *%_)  # My

我希望我的方法在他们之前被调用。如何修改调度程序?

命名参数无关紧要;这里没有。问题是问题中的代码没有添加更具体的 multi 候选,而是试图替换 proto。如果改为像这样添加 multi 候选人:

use MONKEY-TYPING;
augment class Array { 
    multi method AT-POS(Array:D: Int:D $i where $i < 0) {
        nextwith($i + self.elems)
    }
}

然后,由于 where 子句的存在,它会在通常没有的 AT-POS 候选人之前被考虑。由于标准候选人仍然适用,因此可以使用 nextwith 来推迟它。使用上面的augment,程序:

my @arr = 1, 2, 3;
my $idx = -1;
say @arr[$idx];

会输出3.

有关 augment 的常见注意事项适用,并且由于每个数组索引操作都会支付此费用,因此预计会出现显着的减速。