- 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/
我正在编写一个插件,有一个ajax调用向用户显示数据。 如果用户想在ajax成功时添加一些js?他可以从他的 js 脚本中做到这一点吗,比如定位这个 ajax 成功事件。 例如: $(documen
我有 html 代码,例如 - x 最初插入 div 'insert_calendar_eda_form'。 Javascript代码 calendar_eda_add
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 3 年前。 Improve this qu
我已经使用命令 sudo start myservice 启动了一个 upstart 服务。我想要一种方法,以便稍后我(或任何人)可以检查该服务是否已启动并正在运行。检查它的命令是什么? 最佳答案 找
我是一名优秀的程序员,十分优秀!