代码之家  ›  专栏  ›  技术社区  ›  rampion

使用Ruby的OptionParser解析子命令

  •  23
  • rampion  · 技术社区  · 14 年前

    我希望能够使用Ruby的OptionParser解析表单的子命令

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

    像:

    git branch -a
    gem list foo
    

    我知道我可以切换到一个不同的选项解析器库(比如trollop),但是我有兴趣从选项解析器中学习如何做到这一点,因为我想更好地学习这个库。

    有什么小窍门吗?

    4 回复  |  直到 11 年前
        1
  •  38
  •   rampion    14 年前

    明白了。我需要使用 OptionParser#order! . 它将从开始分析所有选项 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!
    
        2
  •  1
  •   jmace    13 年前

    看起来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
    
        3
  •  0
  •   Ken Bloom    14 年前

    你还可以看到其他宝石,比如 main .

        4
  •  0
  •   Alan Cabrera    11 年前

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

    推荐文章