【问题标题】:How do I get only long options work in OptionParser in Ruby?如何在 Ruby 中的 OptionParser 中仅使用长选项?
【发布时间】:2013-12-18 09:23:54
【问题描述】:

我在 Ruby (test.rb) 中有这么简单的代码:

#! /usr/bin/env ruby

require 'optparse'

OptionParser.new do |option|
  option.on("--sort", "Sort data") do 
    puts "--sort passed"
  end
end.parse!

然后我运行它:./test.rb -s 并得到:

--sort passed

我错过了什么吗?

我希望唯一的--sort(长)选项有效,而不是短选项。

我如何获得它?

【问题讨论】:

  • 这个答案有帮助吗?

标签: ruby optionparser


【解决方案1】:

我在 optparse.rb 第 1378-1380 行找到了导致此行为的代码:

# if no short options match, try completion with long
# options.
sw, = complete(:long, opt)

如果您不喜欢这种行为,您最好的选择似乎是在您的项目中创建optparse.rb 的副本,删除副本中的有问题的rescue InvalidOption 子句,并删除load 而不是标准库的版本。

【讨论】:

    【解决方案2】:

    如果您定义以相同字母开头的相似长选项,这是一个有趣的行为,在示例中为s。它不允许使用-s 键,但OptionParser::AmbiguousOption 除外,但似乎没有办法在不侵入其代码的情况下禁用OptionParser 的短选项:

    #! /usr/bin/env ruby
    
    require 'optparse'
    
    OptionParser.new do |option|
      option.on("--sport", "Sport data") do
        puts "--sport passed"
      end
      option.on("--sort", "Sort data") do
        puts "--sort passed"
      end
    end.parse!
    

    这是on方法的扩展版:

    OptionParser.new do |option|
      opts = [ "--sort", "Sort data" ]
      sw = option.make_switch(opts) 
      block = proc { puts "--sort passed" }
      sw[0].instance_variable_set :@block, block
      option.top.append *sw
      p sw
      # => [#<OptionParser::Switch::NoArgument:0x806c770 @pattern=/.*/m, @conv=#<Proc:0x806dd8c@/home/malo/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/optparse.rb:1617>, @short=[], @long=["--sort"], @arg=nil, @desc=["Sort data"], @block=#<Proc:0x806c70c@./1.rb:8>>, [], ["sort"], nil, []]
    end.parse!
    # => --sort passed when  ./1.rb --sort and ./1.rb -s
    

    有趣的是,@short 变量为空,但应用程序对-s 键作出反应。

    我更喜欢使用micro-optparse gem。按如下方式使用:

    宝石文件

    gem 'micro-optparse', :git => 'https://github.com/3aHyga/micro-optparse.git', :branch => 'no-short' # for now it is available only from git repo
    

    ruby_script.rb

    require 'micro-optparse'
    
    options = Parser.new do |p|
       p.banner = "This is a fancy script, for usage see below"
       p.option :sport, "sport", :default => "Sport", :short => "p"
       p.option :sort, "sort", :default => "Sort", :short => false
    end.process!
    
    p options
    

    模拟:

    $ bundle exec ./1.rb --sort 111
    {:sport=>"Sport", :sort=>"111"}
    
    $ bundle exec ./1.rb -s 111
    ambiguous option: -s
    
    $ bundle exec ./1.rb -p 111
    {:sport=>"111", :sort=>"Sort"}
    

    【讨论】:

      【解决方案3】:

      您可以重新打开 OptionParser::OptionMap 以禁用完成:

      class OptionParser::OptionMap
        def complete(key, icase = false, pat = nil)
          # disable completions
          nil
        end
      end
      
      

      这将禁用搜索要完成的内容的预定义行为。

      【讨论】:

        【解决方案4】:

        我的程序有一个参数“--sort”,它可以接受“-s”、“s”、“+s”等参数

        在这种情况下,您可以将一组有效参数传递给您的选项:

        require 'optparse'
        
        OptionParser.new do |option|
          option.on("--sort TYPE", %w(-s s +s), "Sort data") do |type|
            puts "--sort passed with argument #{type}"
          end
        end.parse!
        

        用法:

        $ ./test.rb --sort -s
        --sort passed with argument -s
        $ ./test.rb --sort s
        --sort passed with argument s
        $ ./test.rb --sort +s
        --sort passed with argument +s
        

        请注意,您仍然可以使用简写 -s

        $ ./test.rb -s -s
        --sort passed with argument -s
        $ ./test.rb -s s
        --sort passed with argument s
        $ ./test.rb -s +s
        --sort passed with argument +s
        

        【讨论】:

        • 有效参数未知。我的意思是我只能说它会是这样的:'-something',或'something',或'+something'。它是减号、加号或无号,但它后面的单词是什么 - 是未知的。我可以在那里使用正则表达式吗?
        【解决方案5】:

        从文档看来,这是不可能的。

        #on 方法使用#make_switch 的语法,描述为here。整个文档都没有提到能够打开或关闭长变量或短变量。

        但是,这真的是个问题吗?按照惯例,可以通过长名称和短名称访问选项,强制更改该行为可能会让您的用户感到沮丧。

        如果您真的不想使用短名称,最好的选择是查看其他一些库(例如 highline、slop、trollop)或自行开发。

        【讨论】:

        • 我的程序有一个参数'--sort',它可以接受'-s'、's'、'+s'等参数。所以我真的不想允许短名称.
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-26
        • 2014-08-10
        • 1970-01-01
        • 2012-04-30
        • 1970-01-01
        相关资源
        最近更新 更多