Как получить все подписи multi sub или build-ins?

Я определил multi sub которая имеет две подписи:

multi sub mie(Str $s, Int $i) { $s x $i }
multi sub mie(Int $s, Int $i) { ... }
say &mie.signature; # ;; Mu | is raw)

Я хочу получить подпись этого multi sub, но вышеупомянутый результат не то, что я ожидал.

Как сказано в документе, содержит метод multi, который имеет 4 подписи:

multi method contains(Str:D: Cool:D $needle)
multi method contains(Str:D: Str:D $needle)
multi method contains(Str:D: Cool:D $needle, Int(Cool:D) $pos)
multi method contains(Str:D: Str:D $needle, Int:D $pos)

Но когда я пытаюсь получить подпись содержит:

say "a string".^methods.pairs.values[8].value.signature; 

Выводится только одна подпись:

(Str: | is raw)

В REPL, когда я звоню contains Метод без аргумента выдает следующую ошибку:

> "a string".contains()
Cannot resolve caller contains(Str: ); none of these signatures match:
    (Str:D: Cool:D $needle, *%_)
    (Str:D: Str:D $needle, *%_)
    (Str:D: Cool:D $needle, Cool:D $pos, *%_)
    (Str:D: Str:D $needle, Int:D $pos, *%_)
  in block <unit> at <unknown file> line 1

Это указывает на то, что contains Метод действительно имеет 4 подписи! Я хочу знать, есть ли какие-либо методы, которые могут выводить все сигнатуры метода / мульти-метод?

3 ответа

Решение

Пытаться "a string".^lookup('contains').candidates».signature

.^lookup('contains') найдет Method

.candidates перечислю несколько кандидатов

.signature даст вам Signature для каждого.

Выход: ((Str:D: Cool:D $needle, *%_) (Str:D: Str:D $needle, *%_) (Str:D: Cool:D $needle, Cool:D $pos, *%_) (Str:D: Str:D $needle, Int:D $pos, *%_))

Вы можете использовать его для вашего multi sub тоже:

say &mie.candidates».signature;

В качестве дополнения к ответу Курта:

proto foo (;; Mu | is raw) {*}   # proto(;; Mu | is raw)

multi foo ($a)             { }   # multi($a)
multi foo (Int $a)         { }   # multi(Int $a)

multi foo ($a,$b)          { }   # multi($a, $b)
multi foo (Int $a,$b)      { }   # multi(Int $a, $b)

say 'proto', .signature for &foo;            # displays 1 line
say 'multi', .signature for &foo.candidates; # displays 4 lines

Я показал результаты say s вместе с их соответствующими процедурами.

Если вы позвоните foo ... где foo это процедура множественной отправки (то же самое с .foo) тогда, по крайней мере, семантически, вы на самом деле называете proto заявлено для этого имени, что затем (обычно) повторно отправляется в лучшую multi с тем же именем. Если вы вызываете методы на &foo тогда вы звоните им на proto за foo,

Заявлено вручную proto обеспечивает полный контроль над процессом отправки. Он может сделать чашку чая и затем использовать семантику рассылки Common Lisp, а затем возиться с результатом. Или что еще он хочет сделать.

Если один или несколько multi s объявляются без явного объявления proto тогда по умолчанию proto генерируется автоматически. Я вручную объявил proto это показывает, что это по умолчанию:

  • ;; исключает параметры в proto от того, что он имеет отношение к первоначальной отправке;

  • Mu явно дает общий тип списка аргументов, передаваемый как можно более широкому типу (потому что, если вы не укажете, он будет более узким Any по параметрам);

  • По умолчанию proto получает все аргументы (вот что | в паренсе);

  • Аргументы получены в необработанном виде (is raw);

  • Тело отправляется на следующую одноименную процедуру (вот что {*} делает).

Я сделал P6Repl::Helper модуль некоторое время назад для этой цели.

Другие вопросы по тегам