如上所述,命令行在操作系统将命令交给 Ruby 之前被解析。通配符正在扩展为以空格分隔的文件名列表。
您可以看到如果您echo *在命令行键入类似的内容会发生什么,然后,而不是点击Return,而是点击Escthen *。您应该会看到*扩展的匹配文件列表。
击中Return这些名称后,将被添加到 ARGV 数组中。OptionParser 将遍历 ARGV 并找到您定义的标志,如有必要,获取以下元素,然后将它们从 ARGV 中删除。当 OptionParser 完成时,任何不适合选项的 ARGV 元素将保留在 ARGV 数组中,您可以在其中获取它们。
在您的代码中,您正在寻找'-a'or'--add FILE'选项的单个参数。OptionParser 有一个Array选项,它将从命令行获取逗号分隔的元素,但随后将使用空格分隔的元素。
require 'optparse'
options = []
opts = OptionParser.new
opts.on('-a', '--add FILE', Array) do |s|
options << s
end.parse!
print "options => ", options.join(', '), "\n"
print "ARGV => ", ARGV.join(', '), "\n"
将其保存到文件并尝试使用命令行-a one two three,然后使用-a one,two,three. 您将看到该Array选项如何根据参数之间是否有逗号或空格以不同方式抓取元素。
因为*通配符被替换为空格分隔的文件名,所以您必须在 OptionParser 对它运行后对 ARGV 进行后处理,或者以编程方式全局化目录并以这种方式构建列表。ARGV 拥有除选项中选择的文件之外的所有文件,-a因此,就我个人而言,我会放弃该-a选项并让 ARGV 包含所有文件。
*如果文件太多并且超出缓冲区大小,您将不得不对目录进行全局化。您会知道是否会发生这种情况,因为操作系统会抱怨。