具有异常处理的Ruby optparse奇数行为
我正致力于通过对该工具的CLI组件进行错误处理,使CLI ruby工具更加健壮。我正在使用optpasse,文档显示标志可以有强制参数和可选参数。我只是看到一些奇怪/恼人的行为 对于一种情况,标志的参数是强制性的(使用等号),我试图让它失败,但它仍然有效,它只是抓住了下一个标志('-u')作为该标志的参数,这会导致其余的解析以一种不太理想的方式进行。我想这是可以的,因为“-…”可能有效,但因为我使用等号设置开关的值,所以我假设“空格”样式的赋值不起作用具有异常处理的Ruby optparse奇数行为,ruby,arguments,command-line-interface,optionparser,Ruby,Arguments,Command Line Interface,Optionparser,我正致力于通过对该工具的CLI组件进行错误处理,使CLI ruby工具更加健壮。我正在使用optpasse,文档显示标志可以有强制参数和可选参数。我只是看到一些奇怪/恼人的行为 对于一种情况,标志的参数是强制性的(使用等号),我试图让它失败,但它仍然有效,它只是抓住了下一个标志('-u')作为该标志的参数,这会导致其余的解析以一种不太理想的方式进行。我想这是可以的,因为“-…”可能有效,但因为我使用等号设置开关的值,所以我假设“空格”样式的赋值不起作用 op = OptionParser.new
op = OptionParser.new do |x|
x.on("-u", "--user=USER", "user flag") do |user| options[:user] = user end
x.on("-d", "--db=DATABASE", "database flag") do |db| options[:db] = db end
end
如果我传递以下CLI输入:
myprog -u -d mydb positionalarg
然后在解析过程中,它将options[:user]设置为-d,options[:db]为nil,因为没有遇到它,并且有2个位置参数,而不是1个。显然这是一个用户错误,但我希望捕获它并显示一个真正的错误,而不仅仅是返回一个错误(在工具的情况下),即只能从以下列表中传递一个位置参数:。。。真正的问题是-u标志缺少它所需的参数,所以假设optparse有一个ArgumentMissing异常,我假设这就是.parse!我会扔
但是,对于具有可选参数(使用等号)的标志,如果您这样做,它实际上是可选的:-a-b=something,但这不起作用:-a something-b=somethingelse。强制该值的唯一方法是使用等号:-a=something-b=somethingelse。考虑到之前的行为,强制论点带有等号,我不认为会是这样。例如:
op = OptionParser.new do |x|
x.on("-u", "--user[=USER]", "user flag") do |user| options[:user] = user unless user.nil? end
x.on("-d", "--db=DATABASE", "database flag") do |db| options[:db] = db end
end
因此,对于解析:
myprog -u -d mydb positionalarg
myprog -d mydb -u positionalarg
然后,options[:user]是nil(ok),options[:db]是mydb,剩下一个位置参数
通过此解析:
myprog -u myuser -d mydb positionalarg
然后options[:user]为nil(不正常),options[:db]为mydb,剩下两个位置参数:myuser和positionarg(不正常)。我的错误检查再次显示位置arg计数。似乎如果使用强制标志参数,如果空格和=都起作用,那么对于可选标志参数,应该是相同的,但情况并非如此
另一个问题是,带有可选参数(使用空格)的标志没有问题,除非它们位于命令末尾,然后将位置参数作为标志参数
例如:
op = OptionParser.new do |x|
x.on("-u", "--user [USER]", "user flag") do |user| options[:user] = user unless user.nil? end
x.on("-d", "--db=DATABASE", "database flag") do |db| options[:db] = db end
end
因此,对于解析:
myprog -u -d mydb positionalarg
myprog -d mydb -u positionalarg
然后,options[:db]是mydb(ok),options[:user]是positionalg,并且没有剩余的位置参数。请注意,-d mydb可以使用空格,即使是我用等号指定的空格
似乎很多人都是通过optparse.parse来实现ruby CLIs的!并将ARGV中的其余条目作为位置参数,但我认为在将ARGV传递给optpasse之前,最好先从远端去掉位置参数(除非在位置参数数量可变的情况下失败)
我相信我可以围绕所有这些进行编程,但如果在OptPass中有我不知道的方法,我宁愿不这样做
也许最好的办法是避免使用带有可选参数的标志:),但任何建议都将不胜感激。为什么在选项定义中使用
=
?中的示例不使用它们
如果我将此MWE定义为test.rb
:
require 'optparse'
puts "\n=Call with #{ARGV.inspect}"
options = {}
op = OptionParser.new do |x|
x.on("-u", "--user [USER]", "user flag") do |user| options[:user] = user unless user.nil? end
x.on("-d", "--db DATABASE", "database flag") do |db| options[:db] = db end
end
op.parse!
puts "Options: #{options.inspect}"
puts "ARGV #{ARGV.inspect}"
并使用此batfile调用它(Windows,为Linux删除@echo off
):
我得到:
=Call with ["-h"]
Usage: test [options]
-u, --user [USER] user flag
-d, --db DATABASE database flag
=Call with ["-u", "-d", "mydb", "positionalarg"]
Options: {:db=>"mydb"}
ARGV ["positionalarg"]
=Call with ["-u", "myuser", "-d", "mydb", "positionalarg"]
Options: {:user=>"myuser", :db=>"mydb"}
ARGV ["positionalarg"]
=Call with ["--user=myuser", "-d", "mydb", "positionalarg"]
Options: {:user=>"myuser", :db=>"mydb"}
ARGV ["positionalarg"]
你为什么不告诉我们你在做什么,而不是试图描述它?源代码就像一张图片,价值千言万语。实际上,这不是一个有用的问题:“关于您编写的代码问题的问题必须在问题本身中描述特定的问题,并包括重现问题的有效代码。请参阅以获取指导。”在长格式标志中使用等号是执行CLI长格式标志的惯用方法,而短格式通常不使用等号。