Прямо сейчас у меня есть подпрограмма MAIN
, которая может принимать один или несколько строковых аргументов. Но для этого я использую два отдельных параметра для MAIN
:
sub MAIN (
Str:D $file,
*@files,
) {
@files.prepend: $file;
# Rest of the program
}
Теперь мне интересно, есть ли более идиоматический способ добиться этого, поскольку мое текущее решение кажется немного неуклюжим и не очень Perly.
Как минимум 1 аргумент. Я думал, что могу добавить ограничение к *@files
, чтобы гарантировать, что он содержит более 0 элементов, но вы не можете добавить к нему ограничение типа Str
(как в Str *@files
), и я хочу, чтобы это было для текста USAGE
по умолчанию.
Возможно, здесь достаточно хороший ответ:
sub MAIN(*@a where {.elems > 0 and .all ~~ Str}) {
say "got at least 1 file name"
}
sub USAGE {
say "{$*PROGRAM-NAME}: <file-name> [ <file-name> ... ]"
}
На основе документов здесь: https://docs.perl6.org/type/Signature#Constraining_Slurpy_Arguments
Вы также можете попробовать использовать просто динамические переменные:
die "Usage: $*EXECUTABLE <file> <file2>*" if !+@*ARGS;
my @files = @*ARGS;
где @*ARGS
- это массив с аргументами, выданными в командной строке
Вы даже можете использовать @*ARGFILES
, поскольку на самом деле это файлы
Вы можете сделать это с помощью proto sub
proto sub MAIN ( $, *@ ){*}
multi sub MAIN ( *@files ) {
# Rest of the program
}
или с удаление суб-подписи
sub MAIN ( *@files ($,*@) ) {
# Rest of the program
}
Рискуя "лишний ответ" - мой взгляд на "Перли" краток, насколько это возможно, но не становится непонятным (возможно, я просто заменяю один субъективный термин двумя другими ... :-)
Если у вас есть массив «slurpy» в качестве единственного параметра, он с радостью не примет никаких аргументов, выходящих за рамки спецификации, которую вы указали в комментариях. Тем не менее, позиционный параметр является обязательным по умолчанию, а прото необходимы только в том случае, если вы хотите исключить ограничения для всех мультиов - по-видимому, излишек для того, что вы хотите здесь. Итак, этого достаточно:
sub MAIN($file , *@others) {
say "Received file, $file, and @others.elems() others."
}
Это близко к тому, что поставил mr_ron, но почему бы не пойти с сообщением об использовании по умолчанию, которое MAIN любезно подсказывает вам, исследуя ваши параметры:
$ ./f.pl
Usage:
./f.pl <file> [<others> ...]
Кто-то может сказать, что я обманул, отказавшись от ограничения типа Ул. для первого параметра, но на самом деле это не очень выгодно, когда вы ограничиваете строки, потому что числа, указанные в CLI, передаются как тип IntStr (своего рода гибридный тип) который удовлетворяет ограничению Str. OTOH, при ограничении параметров CLI значением Num или Int, Perl6 проверит, действительно ли вы помещаете туда цифры - или, по крайней мере, то, что Unicode считает цифрами.
Если вам нужны настоящие имена файлов, вы можете сэкономить шаг проверки, ограничившись вводом IO()
. Тогда это будет работать, только если вы дадите файлу имя. И, наконец, установка where .r
после параметра будет настаивать на том, чтобы он был доступен для чтения при загрузке:
sub MAIN(IO() $file where .r, *@others) { ...
Одна короткая строка, которая настаивает на одном обязательном аргументе, который является именем файла, ссылающимся на читаемый файл, с различным количеством других параметров и полезным сообщением об использовании, автоматически сгенерированным, если все идет боком ...
Использование ограничения типа IO
интересно, я не учел его. Я также очень предпочитаю придерживаться USAGE
по умолчанию, поскольку это одна из функций, которые я хочу выделить в создаваемом мной коде.
«Мой взгляд на« Перли »краток, насколько это возможно, но не становится непонятным» - это, как вы говорите, субъективное и умножающееся на концепции. Это также слишком стесняет "Перли" имо. Но, тем не менее, ваша точка зрения находит отклик. Предлагаю назвать этот подход словом «сравнял». Это неясно, но правдоподобно настолько же лаконично, насколько разумно, учитывая, что мы можем связать с определение, которое я намерен, а затем спорить о том, что означает «разрушенный», включая споры о предположениях относительно предположений, при этом общая основа состоит в том, что мы должны стремиться к общему согласию по образцам хорошего уничтожения. .
Fwiw, я думаю, и твой ответ, и ответ Брэда - отличные бритвы.
«Это непонятно, но правдоподобно настолько же лаконично, насколько и разумно ...» - это предложение напоминает мне попытку понять протоколы метаобъектов: -) ... но я понимаю вашу точку зрения - попытка пригвоздить перли была очень неуместной с моей стороны
Tyil - имейте в виду, что вы получаете эффект, ограничивая IO (), включая скобки. Включение скобок требует приведения аргумента к типу.
Вы хотите, чтобы ваш скрипт также принимал 0 аргументов? Или у него должен быть хотя бы 1 аргумент. Если последнее, то это способ сделать это, AFAIK.