首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有子命令的OptionParser

带有子命令的OptionParser
EN

Stack Overflow用户
提问于 2015-07-20 17:38:36
回答 2查看 1.3K关注 0票数 1

我正在尝试使用OptionParser创建一个带有子命令的命令行程序。我在跟着"用于获取子命令的ruby的OptionParser“。

问题在于它不允许像这样的用例:

代码语言:javascript
复制
ruby main.rb --version 
#=> main.rb in `<main>': undefined method `order!' for nil:NilClass (NoMethodError)

但它确实允许这样做:

代码语言:javascript
复制
ruby main.rb foo --options
ruby main.rb --options foo
ruby main.rb --options foo --options

在没有给出子命令的情况下,如何正确处理命令行参数。

我的示例代码是:

代码语言:javascript
复制
global = OptionParser.new do |opts|
  opts.banner = "Usage: opt.rb [options] [subcommand [options]]"
  opts.on("-v", "--version", "Print the version") do |v|
    options[:version] = v
  end
  opts.separator ""
  opts.separator subtext
end
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-20 19:08:53

带有错误的行:

代码语言:javascript
复制
global.order!
command = ARGV.shift
subcommands[command].order!

如果global.order!使用所有的ARGV,那么命令就是nil。所以..。去查一下。

代码语言:javascript
复制
global.order!
command = ARGV.shift
unless command
  STDERR.puts "ERROR: no subcommand"
  STDERR.puts global # prints usage
  exit(-1)
end
subcommands[command].order!
票数 1
EN

Stack Overflow用户

发布于 2015-07-20 18:50:36

也许这会有帮助:

代码语言:javascript
复制
require 'optparse'

VERSION = '1.0.0'

options = {}
OptionParser.new do |opt|
  opt.on('-f', '--foo', 'Foo it') { |o| options[:foo] = o }

  opt.on_tail('-v', '--version') do
    puts VERSION
    exit
  end

end.parse!

puts options

将其保存为"test.rb“,并使用ruby test.rb返回运行它:

代码语言:javascript
复制
{}

使用ruby test.rb -f--foo运行它将返回:

代码语言:javascript
复制
{:foo=>true}

使用ruby test.rb -v--version运行它将返回:

代码语言:javascript
复制
1.0.0

为了获得更多乐趣,运行ruby test.rb -h--help返回:

代码语言:javascript
复制
Usage: test [options]
    -f, --foo                        Foo it

尽管我没有定义-h--help

如果我希望-v--version标志出现在列表中,那么我会将它们从on_tail方法更改为普通的on方法:

代码语言:javascript
复制
require 'optparse'

VERSION = '1.0.0'

options = {}
OptionParser.new do |opt|
  opt.on('-f', '--foo', 'Foo it') { |o| options[:foo] = o }

  opt.on('-v', '--version', 'Returns the version') do
    puts VERSION
    exit
  end

end.parse!

puts options

它将返回:

代码语言:javascript
复制
Usage: test [options]
    -f, --foo                        Foo it
    -v, --version                    Returns the version

我可以补充如下:

代码语言:javascript
复制
puts ARGV

到脚本的末尾,并确保OptionParser正确地处理标志和参数:

代码语言:javascript
复制
>ruby test.rb bar --foo
{:foo=>true}
bar

>ruby test.rb --foo bar
{:foo=>true}
bar

有关更多信息,请参见"通过命令行将变量传递给Ruby脚本“。

示例代码不可能使用--options处理示例输入。没有为--options定义处理程序。subtext也不是。您的代码返回:

代码语言:javascript
复制
undefined local variable or method `subtext' for main:Object (NameError)

将街区剥离至:

代码语言:javascript
复制
global = OptionParser.new do |opts|
  opts.on("-v", "--version", "Print the version") do |v|
    options[:version] = v
  end
end

并再次运行返回:

代码语言:javascript
复制
invalid option: --options (OptionParser::InvalidOption)

所以,同样,你的例子与你说的结果不一致。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31522912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档