我需要解析一个命令行
script.rb <mandatory filename> [options]
与optparse。
当然我可以编写一些自定义代码来处理文件名,然后传递ARGV
给 optparse,但也许有更简单的方法可以做到这一点?
编辑:还有另一种 hacky 方法来解析这样的命令行,那就是传递['--mandatory-filename'] + ARGV
给 optparse,然后处理--mandatory-filename
选项。
首先parse!
使用 optparse,然后扫描 ARGV 并在 ARGV 为空时引发。像这样:
op.parse!
filename = ARGV.pop
raise "Need to specify a file to process" unless filename
强制文件名将不会被处理,OptionParser
并将在 ARGV 中留给您 - 如果它不存在,只需手动提升。
只是为了跟进 Julik 和 Shadowfirebird 所说的话:解析时OptionParser
要注意这一点parse!
并parse
具有不同的功能。前者将从传递的数组中删除它理解的每个参数,后者将保留它们。这会改变您确定所需参数是否存在的条件。
虽然它并不适用于所有情况,但能够在单个命令行上处理多个文件通常很不错,例如:
script.rb [options] file1 file2 ...
file1 是必需的,但 file2 及以后是可选的。
我知道的最好的方法是遵循这个约定:
options = {}
optparse = OptionParser.new do |opts|
opts.banner = "Usage: script.rb [options] file1 file2 ..."
opts.on('-a', '--an-option ARG', 'Set some option') do |arg|
options[:a] = arg
end
...
end
optparse.parse!
# Check required conditions
if ARGV.empty?
puts optparse
exit(-1)
end
如果未提供文件,将显示一条帮助消息,其中包含使用横幅和选项说明。如果文件存在,它们将是 ARGV 中唯一剩下的东西。
我不确定它是否是最近添加的,但之前的答案都没有提到optparse.parse
在删除解析的选项后将返回 ARGV 值。
如果你这样做:
rest = optparse.parse!
您将获得一个包含给定文件的数组(以及未知选项)。这样您就不必关心选项是在文件之前还是之后。
Optparse 只做带参数的参数,AFAIK。处理文件名的“正确”方法是在 optparse 之外处理它。我为此发布了一些示例代码来回答这个问题。
顺便说一句,这是一个相当不寻常的命令行。如果它只适合你,很好,但其他人可能会觉得它相当违反直觉。有以下情况会更正常:script.rb [options] <filename>
...