Я работал над созданием рубинового инструмента CLI немного более надежным с обработкой ошибок компонента CLI инструмента. Я использую optparse, и документация показывает, что флаги могут иметь обязательные и необязательные аргументы. Я просто вижу какое-то странное/раздражающее поведение.Нечетное поведение Ruby optparse с обработкой исключений
Для одного случая, когда аргумент флага является обязательным (с использованием знака равенства), я пытался сделать его неудачным, но он все еще работал, он просто захватил следующий флаг ('-u') в качестве аргумента для этот флаг вместо этого приводит к тому, что оставшаяся часть синтаксического анализа становится более чем идеальной. Я предполагаю, что это вроде ОК, так как «-....» может быть действительным, но поскольку я использую знак равенства для установки значения переключателя, я бы предположил, что присвоение стиля «пробел» не будет работать ,
op = OptionParser.new do |x|
x.on("-u", "--user=USER", "user flag") do |user| options[:user] = user end
x.on("-d", "--db=DATABASE", "database flag") do |db| options[:db] = db end
end
Если я прохожу следующий вход CLI:
myprog -u -d mydb positionalarg
Затем во время синтаксического анализа, он задает параметры [: пользователя], чтобы быть -d и опции [: дБ] равна нулю, так как он не является и есть 2 позиционных аргумента вместо 1. Очевидно, что это ошибка пользователя, но я хочу поймать ее и отобразить реальную ошибку, а не просто вернуть ошибку (в случае инструмента), что должен быть принят только один позиционный аргумент из следующего списка: ... Истинная проблема в том, что флаг -u отсутствует, это требуемый аргумент, так что если у optparse есть исключение ArgumentMissing, я бы предположил, что это то, что .parse! будет бросать.
Однако с флагом, который имеет необязательный аргумент (с использованием знака равенства), на самом деле это необязательно, если вы делаете: -a -b = что-то, но это не работает: -a something -b = somethingelse. Единственный способ заставить значение - использовать знак равенства: -a = something -b = somethingelse. Учитывая предыдущее поведение с обязательным аргументом с равным знаком, я бы не подумал бы об этом. Пример:
op = OptionParser.new do |x|
x.on("-u", "--user[=USER]", "user flag") do |user| options[:user] = user unless user.nil? end
x.on("-d", "--db=DATABASE", "database flag") do |db| options[:db] = db end
end
Так с разбором:
myprog -u -d mydb positionalarg
Затем опции [: пользователь] является нулевыми (КИ) и опция [: дБ] является MYDB и есть одна позиционная агд осталась.
С этим разбором:
myprog -u myuser -d mydb positionalarg
Затем опции [: пользователь] равен нуль (не в порядке) и опция [: дБ] является MYDB и есть два позиционные арг перенесенный: MyUser и positionalarg (не в порядке). Моя ошибка снова проверяется с помощью позиционного аргумента arg. Кажется, что если с обязательными аргументами флага, что если оба пространства и = работают, то для необязательных аргументов флага они должны быть одинаковыми, но это не так.
Другая проблема заключается в том, что флаги с необязательными аргументами (используя пробел) являются точными, за исключением случаев, когда они находятся в конце команды, а затем принимают аргумент position как аргумент flags.
Пример:
op = OptionParser.new do |x|
x.on("-u", "--user [USER]", "user flag") do |user| options[:user] = user unless user.nil? end
x.on("-d", "--db=DATABASE", "database flag") do |db| options[:db] = db end
end
Так с разбором:
myprog -d mydb -u positionalarg
Затем опции [: дБ] является MYDB (КИ) и опция [: пользователь] является positionalarg и неты позиционных аргументов остаются над. Обратите внимание, что -d mydb работает с пространством, даже те, которые я указываю с помощью знака равенства.
Кажется, что многие люди делают рубиновые CLI, делая optparse .parse! и взять остальные записи в ARGV в качестве позиционных аргументов, но я думаю, что лучше было бы отделить аргументы позиционирования от дальнего конца, прежде чем передавать ARGV на optparse (за исключением того, что это не выполняется в случае переменного числа позиционных аргументов.
Я уверен, что я могу программировать вокруг всего этого, но я предпочел бы не, если есть способы, чтобы сделать это в optparse, что я не догадывались.
может быть, лучше всего было бы, чтобы избежать флагов с необязательными аргументами :), но любые советы будут оценены.
Почему бы вам не показать, что вы делаете, а не пытаетесь описать его? Исходный код, как картинка, стоит тысячи слов. Как есть, это не вопрос, который можно использовать: «Вопросы, связанные с проблемами с написанным кодом, должны описывать конкретную проблему - и включать в себя действительный код для его воспроизведения - в самом вопросе. См. Http://SSCCE.org для руководства «. –