【发布时间】:2014-01-21 20:25:06
【问题描述】:
我正在努力通过工具的 CLI 组件的错误处理来使 CLI ruby 工具更加健壮。我正在使用 optparse 并且文档显示标志可以具有强制和可选参数。我只是看到一些奇怪/烦人的行为。
对于标志的参数是强制性的(使用等号)的一种情况,我试图让它失败但它仍然有效,它只是抓住了下一个标志('-u')作为那个参数而是标记,这会导致其余的解析以不太理想的方式出现。我想这还不错,因为'-....' 可能是有效的,但是因为我使用等号来设置开关的值,所以我假设'space' 样式分配不起作用.
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
那么 options[:user] 是 nil (ok) 并且 options[:db] 是 mydb 并且剩下一个位置参数。
通过这个解析:
myprog -u myuser -d mydb positionalarg
然后 options[:user] 为 nil(不正常), options[:db] 为 mydb 并且剩下两个位置参数:myuser 和 positionalarg(不正常)。我的错误检查再次与位置 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 -d mydb -u positionalarg
那么 options[:db] 是 mydb (ok) 并且 options[:user] 是 positionalarg 并且没有剩余的位置参数。请注意, -d mydb 可以使用空格,即使是我用等号指定的空格。
似乎很多人通过执行 optparse .parse 来执行 ruby CLI!并将 ARGV 中的剩余条目作为位置参数,但我认为在将 ARGV 传递给 optparse 之前先将位置参数从远端剥离可能会更好(除非在位置参数数量可变的情况下失败。
我相信我可以围绕所有这些进行编程,但如果我不知道在 optparse 中有方法可以做到这一点,我不希望这样做。
也许最好的办法是避免带有可选参数的标志:),但任何建议都会受到赞赏。
【问题讨论】:
-
你为什么不向我们展示你在做什么而不是试图描述它?源代码,像一张图,值一千字。事实上,这不是一个可用的问题:“有关您编写的代码问题的问题必须在问题本身中描述具体问题 - 并包括有效的代码来重现它。有关指导,请参阅SSCCE.org。”跨度>
标签: ruby arguments command-line-interface optionparser