На сегодня осталось рассмотреть возможности для управления поведением именованных аргументов. Возможностей немного, но они есть.
Именованные параметры
Перед тем как начать — вопрос: что должна вывести вот такая программа, если ее запустить без каких-либо параметров?
sub MAIN(:$value) {
say "value=$value"
}
Ответ может показаться неожиданным:
$ perl6 main-6.pl
Use of uninitialized value $value of type Any in string context.
Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful.
in sub MAIN at main-6.pl line 1
value=
Вместо примера использования мы получили сообщение об ошибке, которое говорит о том, что функция MAIN была-таки вызвана. То есть именованные аргументы не являются обязательными.
При этом если указать аргумент, отсутствующий в сигнатуре, все работает как надо:
$ perl6 main-6.pl --key=42
Usage:
main-6.pl [--value=<Any>]
Решение проблемы может быть очень легким: если вы действительно ожидаете параметр, укажите, что он должен быть определен (defined):
sub MAIN(Str:D :$value) {
say "value=$value"
}
Теперь появляется желанный пример использования:
$ perl6 main-6.pl
Usage:
main-6.pl [--value=<Str>]
Именованные и позиционные параметры
Для параметров, в том числе и для именованных, возможно указать значение по умолчанию. Например:
sub MAIN($value, :$key = 'default') {
say "$key=$value"
}
В этом случае программа, запущенная без именованного параметра, тоже покажет пример использования, а не ошибку:
$ perl6 main-7.pl
Usage:
main-7.pl [--key=<Any>] <value>
ОК, но теперь возникает другая проблема. Последняя программа ожидает, что именованный параметр передан до позиционного.
Так работает:
$ perl6 main-7.pl --key=answer 42
answer=42
А так нет:
$ perl6 main-7.pl 42 --key=answer
Usage:
main-7.pl [--key=<Any>] <value>
Чтобы заработало и во втором примере, нужно сообщить об этом через специальную динамическую переменную:
my %*SUB-MAIN-OPTS = :named-anywhere;
sub MAIN($value, :$key = 'default') {
say "$key=$value"
}
Довольно многословно, но как есть. Теперь можно передавать именованные параметры в любом месте командной строки.
Обязательное =
Наконец, следует обратить внимание на то, что значения именованных параметров требуют знака равенства и отсутствие пробелов вокруг него. Запись в командной строке --key answer 42 будет расценена как три аргумента.
А если значение не указано, то оно будет истиной:
$ perl6 main-7.pl --key 42
True=42
Итого, нельзя сказать, что все мегаудобно, но во многих случаях разбор параметров командной строки получается довольно простым.