Использование OptionParser в ruby для разбора подкоманд
Я хотел бы иметь возможность использовать OptionParser ruby для анализа подкоманд в форме
COMMAND [GLOBAL FLAGS] [SUB-COMMAND [SUB-COMMAND FLAGS]]
лайк:
git branch -a
gem list foo
Я знаю, что могу переключиться на другую библиотеку синтаксического анализатора опций (например, Trollop), но мне интересно узнать, как это сделать из OptionParser, так как я хотел бы изучить библиотеку лучше.
Какие-нибудь советы?
4 ответа
Догадаться. Мне нужно использовать OptionParser#order!
, Он будет анализировать все параметры с самого начала ARGV
пока он не найдет не опцию (это не аргумент опции), удалив все, что он обрабатывает из ARGV
и тогда он выйдет.
Так что мне просто нужно сделать что-то вроде:
global = OptionParser.new do |opts|
# ...
end
subcommands = {
'foo' => OptionParser.new do |opts|
# ...
end,
# ...
'baz' => OptionParser.new do |opts|
# ...
end
}
global.order!
subcommands[ARGV.shift].order!
Похоже, синтаксис OptionParser несколько изменился. Мне пришлось использовать следующее, чтобы в массиве arguments были все параметры, не проанализированные объектом opts.
begin
opts.order!(arguments)
rescue OptionParser::InvalidOption => io
# Prepend the invalid option onto the arguments array
arguments = io.recover(arguments)
rescue => e
raise "Argument parsing failed: #{e.to_s()}"
end
GLI - это путь, https://github.com/davetron5000/gli. Отрывок из учебника:
#!/usr/bin/env ruby
require 'gli'
require 'hacer'
include GLI::App
program_desc 'A simple todo list'
flag [:t,:tasklist], :default_value => File.join(ENV['HOME'],'.todolist')
pre do |global_options,command,options,args|
$todo_list = Hacer::Todolist.new(global_options[:tasklist])
end
command :add do |c|
c.action do |global_options,options,args|
$todo_list.create(args)
end
end
command :list do |c|
c.action do
$todo_list.list.each do |todo|
printf("%5d - %s\n",todo.todo_id,todo.text)
end
end
end
command :done do |c|
c.action do |global_options,options,args|
id = args.shift.to_i
$todo_list.list.each do |todo|
$todo_list.complete(todo) if todo.todo_id == id
end
end
end
exit run(ARGV)
Вы можете найти учебник на http://davetron5000.github.io/gli/.
Есть и другие драгоценные камни, которые вы можете посмотреть, например, main.