Как убрать мульти метод в Раку
Как я могу дополнить класс мультиметодом, который будет вызываться перед уже определенным?
Я пытаюсь включить отрицательный индекс: @arr[-1]
как в этой статье, но без изменения источника.
Поэтому я увеличиваю массив с помощью:
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);
}
};
Но как указано в документе
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.
Так что мой мульти никогда не называется:
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
Я хочу, чтобы мой метод вызывался перед их. Как я могу изменить диспетчер?
1 ответ
Именованные параметры не имеют значения; здесь их нет. Проблема в том, что вместо добавления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
применить, и поскольку каждая операция с индексом массива будет оплачивать эту стоимость, следует ожидать значительного замедления.