Использование OptionParser в ruby ​​для разбора подкоманд - PullRequest
23 голосов
/ 29 апреля 2010

Я хотел бы иметь возможность использовать OptionParser в ruby ​​для анализа подкоманд в форме

COMMAND [GLOBAL FLAGS] [SUB-COMMAND [SUB-COMMAND FLAGS]]

как:

git branch -a
gem list foo

Я знаю, что могу переключиться на другую библиотеку синтаксического анализатора опций (например, Trollop), но мне интересно узнать, как это сделать из OptionParser, поскольку я хотел бы лучше изучить библиотеку.

Любые советы?

Ответы [ 4 ]

39 голосов
/ 29 апреля 2010

Разобрался. Мне нужно использовать 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!
1 голос
/ 28 апреля 2011

Похоже, синтаксис 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
0 голосов
/ 15 июля 2013

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/.

0 голосов
/ 29 апреля 2010

Есть также другие драгоценные камни, которые вы можете посмотреть, такие как main .

...