Что делает Any.match? - PullRequest
       47

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

0 голосов
/ 22 февраля 2019

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

 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 или почему она не работает с последовательностями.

Ответы [ 2 ]

0 голосов
/ 23 марта 2019

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

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
>
0 голосов
/ 22 февраля 2019

.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 »должен быть объектом типа типа« Любой », а не экземпляром объекта ...».

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

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

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

A определенный 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: '.'; # 「.」
...