Как получить все подписи 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
модуль некоторое время назад для этой цели.