Могу ли я использовать Ruby OptionParser для принятия произвольного шаблона аргумента?

Допустим, у меня есть простое приложение Ruby, в котором я хочу, чтобы первый аргумент (если есть) указывал среду: TEST, DEVELOPMENT или PRODUCTIONDEVELOPMENT по умолчанию, если аргумент не указан). Например,

ruby myapp.rb test

будет запускать его в режиме TEST. Кроме того, следует принимать сокращения, например,

ruby myapp.rb t

запустит приложение в режиме TEST и

ruby myapp.rb dev

будет запускать его в режиме DEVELOPMENT.

Я хочу использовать OptionParser, но ведет себя очень странно. Если myapp.rb

require 'optparse'

environment = 'DEVELOPMENT'
opts = OptionParser.new
opts.on('test')        { environment = 'TEST' }
opts.on('production')  { environment = 'PRODUCTION' }
opts.parse!(ARGV)

тогда среда становится PRODUCTION независимо от того, какие аргументы я передаю; по какой-то причине opts.on('production') всегда выполняет свой блок. (Это не так, если вместо этого я использую строку в стиле флага, такую ​​​​как '-production'.) И я никак не могу заставить OptionParser искать строки, начинающиеся с «t», а не точную строку «test».

Возможно, OptionParser — неподходящий инструмент для этой работы. Очевидно, было бы тривиально разделить ARGV самостоятельно. Мне просто интересно, что происходит с этим поведением. Я на Руби 1.9.2.


person Trevor Burnham    schedule 19.07.2010    source источник


Ответы (2)


Если вы используете метод parse!, любые аргументы, обрабатываемые вызовами opts.on, удаляются из массива ARGV деструктивно. Это означает, что исходное содержимое массива ARGV больше не будет содержать эти флаги после метода parse!.

Я рекомендую проанализировать оставшийся набор аргументов вручную, сравнив ARGV с массивом, содержащим «тест» и «производство».

Ознакомьтесь с документом: http://ruby-doc.org/stdlib-1.9.3/libdoc/optparse/rdoc/OptionParser.html#method-i-parse-21

person Chris    schedule 29.10.2012

Я бы сказал, что вам нужно разобрать такие аргументы из ARGV перед запуском OptionParser.

e.g.

env = ARGV.select{|arg| arg =~ /dev/test/prod/i}.first

P.S. Я бы порекомендовал Троллоп. Я нахожу это намного проще, и хорошо выбирать значения по умолчанию.

person Blaine Lafreniere    schedule 19.07.2010