- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
有什么办法可以启动OptionParser在一个 Ruby 程序中多次使用,每次都有不同的选项集?
例如:
$ myscript.rb --subsys1opt a --subsys2opt b
在这里,myscript.rb 将使用 subsys1 和 subsys2,将它们的选项处理逻辑委托(delegate)给它们,可能按顺序首先处理 'a',然后在单独的 OptionParser 对象中处理 'b';每次选择仅与该上下文相关的选项。最后一个阶段可以检查每个部分处理完他们的部分后是否没有留下任何未知的东西。
用例是:
在一个松散耦合的前端程序中,各种组件都有不同的参数,我不希望“main”知道所有事情,只是将参数/选项集委托(delegate)给每个部分。
将一些更大的系统(如 RSpec)嵌入到我的应用程序中,我将通过它们的选项简单地传递一个命令行,而我的包装器不知道这些。
我也可以使用一些分隔符选项,例如某些 Java 应用程序中的 --
或 --vmargs
。
在 Unix 世界(startx/X、git plumbing 和 porcelain)中有很多类似事物的现实世界示例,其中一层处理一些选项,但将其余选项传播到较低层。
开箱即用,这似乎行不通。每个 OptionParse.parse!
调用都会进行详尽的处理,在它不知道的任何事情上失败。我想我很乐意跳过未知选项。
欢迎任何提示,也许还有其他方法。
最佳答案
我需要一个永远不会抛出 OptionParser::InvalidOption
的解决方案,并且在当前的答案中找不到一个优雅的解决方案。这个猴子补丁基于 other answers 之一但清理它并使其更像当前的 order!
语义。但请参阅下文,了解多 channel 选项解析固有的未解决问题。
class OptionParser
# Like order!, but leave any unrecognized --switches alone
def order_recognized!(args)
extra_opts = []
begin
order!(args) { |a| extra_opts << a }
rescue OptionParser::InvalidOption => e
extra_opts << e.args[0]
retry
end
args[0, 0] = extra_opts
end
end
就像 order!
一样工作,除了它不是抛出 InvalidOption
,而是在 ARGV
中留下无法识别的开关。
RSpec 测试:
describe OptionParser do
before(:each) do
@parser = OptionParser.new do |opts|
opts.on('--foo=BAR', OptionParser::DecimalInteger) { |f| @found << f }
end
@found = []
end
describe 'order_recognized!' do
it 'finds good switches using equals (--foo=3)' do
argv = %w(one two --foo=3 three)
@parser.order_recognized!(argv)
expect(@found).to eq([3])
expect(argv).to eq(%w(one two three))
end
it 'leaves unknown switches alone' do
argv = %w(one --bar=2 two three)
@parser.order_recognized!(argv)
expect(@found).to eq([])
expect(argv).to eq(%w(one --bar=2 two three))
end
it 'leaves unknown single-dash switches alone' do
argv = %w(one -bar=2 two three)
@parser.order_recognized!(argv)
expect(@found).to eq([])
expect(argv).to eq(%w(one -bar=2 two three))
end
it 'finds good switches using space (--foo 3)' do
argv = %w(one --bar=2 two --foo 3 three)
@parser.order_recognized!(argv)
expect(@found).to eq([3])
expect(argv).to eq(%w(one --bar=2 two three))
end
it 'finds repeated args' do
argv = %w(one --foo=1 two --foo=3 three)
@parser.order_recognized!(argv)
expect(@found).to eq([1, 3])
expect(argv).to eq(%w(one two three))
end
it 'maintains repeated non-switches' do
argv = %w(one --foo=1 one --foo=3 three)
@parser.order_recognized!(argv)
expect(@found).to eq([1, 3])
expect(argv).to eq(%w(one one three))
end
it 'maintains repeated unrecognized switches' do
argv = %w(one --bar=1 one --bar=3 three)
@parser.order_recognized!(argv)
expect(@found).to eq([])
expect(argv).to eq(%w(one --bar=1 one --bar=3 three))
end
it 'still raises InvalidArgument' do
argv = %w(one --foo=bar)
expect { @parser.order_recognized!(argv) }.to raise_error(OptionParser::InvalidArgument)
end
it 'still raises MissingArgument' do
argv = %w(one --foo)
expect { @parser.order_recognized!(argv) }.to raise_error(OptionParser::MissingArgument)
end
end
end
问题:通常 OptionParser 允许缩写选项,前提是有足够的字符来唯一标识预期的选项。在多个阶段解析选项打破了这一点,因为 OptionParser 在第一遍中看不到所有可能的参数。例如:
describe OptionParser do
context 'one parser with similar prefixed options' do
before(:each) do
@parser1 = OptionParser.new do |opts|
opts.on('--foobar=BAR', OptionParser::DecimalInteger) { |f| @found_foobar << f }
opts.on('--foo=BAR', OptionParser::DecimalInteger) { |f| @found_foo << f }
end
@found_foobar = []
@found_foo = []
end
it 'distinguishes similar prefixed switches' do
argv = %w(--foo=3 --foobar=4)
@parser1.order_recognized!(argv)
expect(@found_foobar).to eq([4])
expect(@found_foo).to eq([3])
end
end
context 'two parsers in separate passes' do
before(:each) do
@parser1 = OptionParser.new do |opts|
opts.on('--foobar=BAR', OptionParser::DecimalInteger) { |f| @found_foobar << f }
end
@parser2 = OptionParser.new do |opts|
opts.on('--foo=BAR', OptionParser::DecimalInteger) { |f| @found_foo << f }
end
@found_foobar = []
@found_foo = []
end
it 'confuses similar prefixed switches' do
# This is not generally desirable behavior
argv = %w(--foo=3 --foobar=4)
@parser1.order_recognized!(argv)
@parser2.order_recognized!(argv)
expect(@found_foobar).to eq([3, 4])
expect(@found_foo).to eq([])
end
end
end
关于ruby - OptionParser 可以跳过未知选项,以便稍后在 Ruby 程序中处理吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3642331/
我正在编写一个应该在远程服务器上执行命令的小程序(假设是围绕 ssh [hostname] [command] 的相当愚蠢的包装器)。 我想这样执行: ./floep [command] 但是,我有时
我正在尝试 optparse,这是我的初始脚本。 #!/usr/bin/env python import os, sys from optparse import OptionParser pars
使用 OptionParser 进行字符串参数输入和哈希赋值。为单个参数读入多个变量的最佳方法是什么?然后我如何将它们分配给哈希以供引用?这是我目前所拥有的: large_skus = Hash.ne
我的程序中有以下几行 parser = OptionParser() parser.add_option("-t","--TIMEOUT", dest="timeout", type="int",
我正在使用 optparse 模块中的 OptionParser 来解析我使用 raw_input() 获得的命令。 我有这些问题。 1.) 我使用 OptionParser 来解析这个输入,例如。
我有一个 python 选项解析器,可以解析可选的 --list-something 选项。我还希望 --list-something 选项有一个可选参数(一个选项) 使用参数 default="si
编辑: 我编写了使用 OptionParser 优雅地处理命令行输入的代码。我面临着两个重大打击。 传递空开关“-”不会产生错误。当然,有些程序认为这是有效的,但我的程序不应该。 该程序需要两次强制切
我的 Python 脚本(用于待办事项列表)是从命令行启动的,如下所示: todo [options] [command-options] 有些选项不能一起使用,例如 todo add --pos=
如何格式化 OptionParser() 帮助信息的字符串?似乎忽略了换行符?请看下面的代码。 parser = OptionParser() parser.add_option("--s", des
我有一个使用 OptionParser 的脚本,我想为该程序添加配置文件,该文件将具有 option = value 格式和 # comments。有没有办法让 OptionParser 解析文件或某
我发现自己经常这样做: optparse = OptionParser.new do |opts| options[:directory] = "/tmp/" opts.on('-d','--
我正在尝试为我的 Ruby 脚本定义选项,该脚本将消息从用户 A 发送到用户 B 以进行测试。但是,当某些选项的值中有空格时,我无法让它工作。例如: OptionParser.new do |
在以下脚本中,短选项按预期工作,长选项则不然: #!/usr/bin/env ruby require 'optparse' optparse = OptionParser.new do|opts|
这是 OptionParser 的精简版 OptionParser.new do |opts| opts.on('-f', '--format FORMAT', 'output f
下面的代码有效,但当我想将所需参数构建到所需参数的 native OptionParser sytax 中时,我使用 fetch 手动引发所需参数的参数错误: # ocra script.rb --
我在 Ruby 中使用 OptionParser。 我的其他语言如C、Python等,也有类似的命令行参数解析器,它们通常提供一种在没有提供参数或参数错误时显示帮助信息的方法。 options = {
我正在使用 optparse 模块中的 OptionParser 来解析我使用 raw_input() 获得的命令。当我给出 -h 时,它会显示帮助屏幕并退出我的应用程序。我不希望它显示帮助屏幕或退出
以下“parser.add_option”语句有效,但如果脚本在没有选项/参数的情况下运行,它不会提示。如果未指定选项/参数,我希望它默认显示帮助(-h/--help)。 usage = "usage
我试着设置我的脚本来运行这样的东西 ruby Script.rb --ip "192.168.3.206" 但如果没有 ip 参数则使用默认的“192.168.1.1” 我试过这段代码,但它总是返回
我有一个简单的 watir(网络驱动程序)脚本,它可以转到谷歌。但是,我想使用选项解析器在 cmd 中设置一个参数来选择浏览器。下面是我的脚本: require 'optparse' require
我是一名优秀的程序员,十分优秀!