Что делает Any.match?

У него обманчиво простой код:

 method match(Any:U: |) { self.Str; nqp::getlexcaller('$/') = Nil }

Тем не менее, это поведение, которое оно имеет:

(^3).match(1) # OUTPUT: «「1」␤»

Все идет нормально.

say (1,3 ... * ).match(77); # OUTPUT: «Nil␤»

Ooookey. Что сейчас происходит?

say (1,3 ... * ).match(1);    # OUTPUT: «Nil␤»
say (1,3 ... * ).match(/\d/); # OUTPUT: «Nil␤»

Не любит последовательности.

say (^10).match(/\d/); # OUTPUT: «「0」␤»

ОК, снова имеет смысл.

say <a b c>.match(/\w/); # OUTPUT: «「a」␤»

Вернуться к нормальному. Так что, это не нравится Seqs? Я предполагаю, потому что я посмотрел на код других классов и match не переопределено, все они вызывают этот код. Но я не вижу, как это происходит с помощью возврата строки и установки переменной из NPQ или почему она не работает с последовательностями.

1 ответ

Решение

.match поиск иглы в одной строке сена. Бесконечная последовательность преобразуется в '...',

say (1,3 ... 9).Str;        # 1 3 5 7 9
say (1,3 ... 9).match: '1'; # 「1」

say (1,3 ... *).Str;        # ...
say (1,3 ... *).match: '.'; # 「.」

Как я с этим справился

Во-первых, вы смотрите на неправильное определение метода:

method match(Any:U: |) { ... }

Any:U это вроде как Any $ where not .defined за исключением того, что это совпадение, вы получите сообщение об ошибке "Параметр" "подпрограммы" match "должен быть объектом типа типа" Any ", а не экземпляром объекта...".

Но вы передаете определенный Seq, Так что ваши .match вызовы не отправляются в определение метода, который вы просматриваете.

Чтобы узнать, что метод отправляет, используйте:

say (1,3 ... *).^lookup('match').package ; # (Cool)

Определенный Seq Таким образом, будет отправлен в Cool код:

method match(Cool:D: |c) {
    ...
    self.Stringy.match(|c)
}

Итак, дальше:

say (1,3 ... *).^lookup('Stringy').package ; # (Mu)

И код:

multi method Stringy(Mu:D $:) { self.Str }

Итак, проверьте:

say (1,3 ... *).Str; # ...

Бинго.

И подтвердить:

say (1,3 ... *).match: '.'; # 「.」

Принятый ответ прекрасно объясняет, что происходит. Я просто добавляю это, чтобы показать некоторые примеры того, как сделать то, что, по-видимому, предполагал ОП.

doug$ perl6
To exit type 'exit' or '^D'
> say (^3).any.match(/\d/)
any(「0」, 「1」, 「2」)
> say (^3).any.match(/\d/).so
True
> say (^3).any.match(/ <alpha> /).so
False
> say ('a'..'c').any.match(/ <alpha> /).so
True
> # say (0 ... *).any.match(/ \d /).so ## ==> never terminates
Nil
> say (0 ... *).first(/ \d /)
0
> say (0 ... *).first(/ \d\d /)
10
>
Другие вопросы по тегам