我在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
(长)选项有效,而不是短选项。
我如何得到它?
答案 0 :(得分:3)
我在optparse.rb
第1378-1380行找到了导致此行为的代码:
# if no short options match, try completion with long
# options.
sw, = complete(:long, opt)
如果您不喜欢这种行为,最好选择在项目中创建optparse.rb
的副本,删除副本中有问题的rescue InvalidOption
子句,以及{{1}而不是标准库的版本。
答案 1 :(得分:2)
有趣的是,如果您定义以相同字母开头的类似long选项,则示例中为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
变量为空,但app会对-s
键做出反应。
我更愿意使用micro-optparse
gem。使用方法如下:
<强>的Gemfile 强>
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"}
答案 2 :(得分:2)
您可以重新打开 OptionParser::OptionMap 以禁用补全:
class OptionParser::OptionMap
def complete(key, icase = false, pat = nil)
# disable completions
nil
end
end
这将禁用搜索要完成的内容的预定义行为。
答案 3 :(得分:1)
我的程序有一个参数'--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
答案 4 :(得分:0)
从文档中可以看出这是不可能的。
#on
方法使用#make_switch
的语法,其描述为here。整个文档没有提到能够打开或关闭长或短变量。
然而,这真的是一个问题吗?惯例是可以通过长名和短名访问选项,强制改变这种行为可能会使用户感到沮丧。
如果你真的不想让短名字,最好的选择是看一些其他的图书馆(例如高线,slop,trollop)或自己动手。