2014-09-01 5 views
1

у меня есть рубин кли синтаксического анализа сценария и кажется, что есть какая-то регулярное выражение поведения для вариантов разбора:Руби optparse поведение WRT InvalidOption против исключения MissingArgument

op = OptionParser.new do |x| 

     x.on("--output-config PATH", "The filesystem location for the output config file") do |output_config| 
     options[:output_config] = output_config 
     end 

     x.on("-j", "--json", "If this is set, then json is output instead of tabular form") do 
     options[:disp_json] = true 
     end 

     x.on("-h", "--help", "Show this message") do 
     puts op 
     exit 0 
     end 

     x.on("-v", "--version", "Show version") do 
     puts "version #{VERSION_NUMBER}" 
     exit 0 
     end 
    end 


    # do input validation and check leftovers for proper commands 
    begin 
    # parse options, parse! removes elements from ARGV so leftovers are positional arg(s) 
    op.parse!(ARGV) 
    options[:config_file] = ARGV[0] if ARGV[0] 

    rescue OptionParser::InvalidOption, OptionParser::MissingArgument 
    puts "############### #{$!.to_s} ###############" 
    puts "" 
    puts op 
    exit 1 
    end 

Тогда, если я называю это так:

script -a 

Он выводит следующее (ожидаемое поведение)

############### invalid option: -a ############### 

Или

script --output-config 

Он выводит следующее (ожидаемое поведение)

############### missing argument: --output-config ############### 

Так что это, где это становится странным:

script --output 

Он выводит следующее (не ожидаемого поведения)

############### missing argument: --output ############### 

Или

script --ou 

Он выводит следующее (не ожидаемое поведение)

############### missing argument: --ou ############### 

В принципе ничего вы передаете, что регулярное выражение соответствует "выход-конфигурации" передается в блок для

x.on("--output-config PATH".... 

В чем причина действия MissingArgument vs InvalidOption, которое я вижу.

Я использую optparse неправильно или это ошибка в библиотеке?

####### EDIT

Если добавить еще x.on:

x.on("--out PATH", "The filesystem location for the output config file") do |output_config| 
    options[:output_config2] = output_config 
end 

И передавать или -o (одна черточка, то есть короткая форма) или -O (два дефиса), он не генерирует исключение (я специально освобождаю OptionParser :: AmbiguousOption при обработке не выполняется). Вместо этого выполняется кратчайшее совпадение, которое равно --out. Если я передаю -outp, то выполняется более длинный. Кажется, это мне кажется неровным.

####### EDIT 2
> ./my_app --output-c 
############### missing argument: --output-c 

Исключение MissingArgument только отображает флаг, как прошло, а не как 'предполагаемый'. Он четко знает, что он соответствует «--output-config», поэтому я хотел бы знать, что так, чтобы мое сообщение об ошибке было ясным и явным. Есть ли способ, которым я могу определить, какой optparser был сопоставлен в то время, когда было исключено исключение MissingArgument?

ответ

1

Это стандартное поведение с длинными параметрами. У меня возникли проблемы с поиском какой-либо вспомогательной документации, но я использовал эту функцию для длинных параметров, пока я использую длинные параметры (т. Е. С давних времен).

Вы можете видеть это легко с версией GNU из Ls (1):

$ ls --h 
ls: option '--h' is ambiguous 
Try `ls --help' for more information. 

$ ls --he 
Usage: ls [OPTION]... [FILE]... 
List information about the FILEs (the current directory by default). 
Sort entries alphabetically if none of -cftuvSUX nor --sort. 
... 

$ ls --help 
Usage: ls [OPTION]... [FILE]... 
List information about the FILEs (the current directory by default). 
Sort entries alphabetically if none of -cftuvSUX nor --sort. 
... 

Есть несколько вариантов, которые начинаются с --h так --h ошибка опции, есть только один вариант, который начинается с --he так --he - это то же самое, что и --help.

Если добавить --output-pancakes вариант, то вы должны получить жалобу о неоднозначности, если вы говорите, но --output--output-c и --output-p будет работать.

Вы неправильно используете библиотеку. И это не ошибка. Это особенность.

+0

Интересно, посмотрите мое редактирование выше ^^^. – jshort

+0

Но '--out' отличается,' --out' является точным соответствием для опции, поэтому нет никакой двусмысленности. Если я добавлю параметр '--output-pancakes PATH' и просто использую' --output', тогда я получу 'OptionParser :: AmbiguousOption'. Разбор намеренно нечеткий. –

+0

Хорошо, просто подтвердил, что вы сказали, что это правда. Как насчет того, что он берет короткую форму для длинной формы автоматически? Кроме того, если это просто факт, что optparse автоматически пытается сопоставить параметр (т. Е. --ou => --out), то при обнаружении исключения MissingArgument было бы неплохо узнать, какой явно указанный параметр отсутствует аргумент пользователь может увидеть меню справки и узнать, какой вариант имеет необходимый аргумент, который они остановили. – jshort