Как убрать мульти метод в раку - PullRequest
6 голосов
/ 13 апреля 2020

Как я могу дополнить класс мульти-методом, который будет вызываться перед уже определенным?

Я пытаюсь включить отрицательный индекс: @arr[-1] как в this статья, но без изменения источника.

Поэтому я увеличиваю Массив с помощью:

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);
    }
};

Но, как указано в do c

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 Ответ

9 голосов
/ 13 апреля 2020

Именованные параметры не имеют значения; здесь их нет Проблема в том, что вместо добавления multi кандидата, который является более точным c, код в вопросе вместо этого пытается заменить 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, и поскольку каждая операция индекса массива будет оплачивать эту стоимость , ожидайте существенного замедления.

...