Как потребовать один или несколько аргументов в MAIN

Прямо сейчас у меня есть подпрограмма MAIN, которая может принимать один или несколько строковых аргументов. Но для этого я использую два отдельных параметра для MAIN:

sub MAIN (
    Str:D $file,
    *@files,
) {
    @files.prepend: $file;

    # Rest of the program
}

Теперь мне интересно, есть ли более идиоматический способ добиться этого, поскольку мое текущее решение кажется немного неуклюжим и не очень Perly.

Вы хотите, чтобы ваш скрипт также принимал 0 аргументов? Или у него должен быть хотя бы 1 аргумент. Если последнее, то это способ сделать это, AFAIK.

Elizabeth Mattijsen 02.05.2018 15:19

Как минимум 1 аргумент. Я думал, что могу добавить ограничение к *@files, чтобы гарантировать, что он содержит более 0 элементов, но вы не можете добавить к нему ограничение типа Str (как в Str *@files), и я хочу, чтобы это было для текста USAGE по умолчанию.

Tyil 02.05.2018 15:26
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
2
207
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Возможно, здесь достаточно хороший ответ:

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

Tyil 03.05.2018 09:43

«Мой взгляд на« Перли »краток, насколько это возможно, но не становится непонятным» - это, как вы говорите, субъективное и умножающееся на концепции. Это также слишком стесняет "Перли" имо. Но, тем не менее, ваша точка зрения находит отклик. Предлагаю назвать этот подход словом «сравнял». Это неясно, но правдоподобно настолько же лаконично, насколько разумно, учитывая, что мы можем связать с определение, которое я намерен, а затем спорить о том, что означает «разрушенный», включая споры о предположениях относительно предположений, при этом общая основа состоит в том, что мы должны стремиться к общему согласию по образцам хорошего уничтожения. .

raiph 03.05.2018 16:27

Fwiw, я думаю, и твой ответ, и ответ Брэда - отличные бритвы.

raiph 03.05.2018 16:31

«Это непонятно, но правдоподобно настолько же лаконично, насколько и разумно ...» - это предложение напоминает мне попытку понять протоколы метаобъектов: -) ... но я понимаю вашу точку зрения - попытка пригвоздить перли была очень неуместной с моей стороны

Marty 04.05.2018 00:25

Tyil - имейте в виду, что вы получаете эффект, ограничивая IO (), включая скобки. Включение скобок требует приведения аргумента к типу.

Marty 04.05.2018 00:33

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