There are a handful of ways to accept multiple values for a given argument with optparse. Some methods allow space-delimited lists, but each way has its pros and cons. The good news is that these methods can be used interchangeably, so you can always implement multiple methods and let the end-user use the one they like.
Given a script called process_files.rb
, like so:
require 'optparse'
args = { files: [] }
OptionParser.new do |opts|
# Option 1: use an array-type optparse argument
opts.on('--files FILE1,FILE2,...', Array, 'A list of comma-separated files.') do |files|
args[:files].concat(files)
end
# Option 2: use a single-value argument; expect it to be repeated multiple times
opts.on('-f', '--file FILE', 'A single file. Repeat for multiple files.') do |file|
args[:files] << file
end
# Option 3: take a string and split it using whatever delimiter you want
opts.on('--colon-files FILE1:FILE2:...', 'A colon-delimited file list.') do |str|
args[:files].concat(str.split(':'))
end
# Option 4: as above, but quoting the file list on the command line allows space delimiting
opts.on('--spaced-files "FILE1 FILE2 ..."', 'A space-delimited file list.') do |str|
args[:files].concat(str.split(/\s+/))
end
end.parse!
# Option 5: Assume all remaining, unparsed arguments are whitespace-delimited files
args[:files].concat(ARGV)
puts args[:files].inspect
Here are the various ways to feed it a list of files:
$ ruby process_files.rb --files foo,bar,baz
["foo", "bar", "baz"]
$ ruby process_files.rb -f foo -f bar -f baz
["foo", "bar", "baz"]
$ ruby process_files.rb --colon-files foo:bar:baz
["foo", "bar", "baz"]
$ ruby process_files.rb --spaced-files 'foo bar baz'
["foo", "bar", "baz"]
$ ruby process_files.rb foo bar baz
["foo", "bar", "baz"]
$ ruby process_files.rb --files apple,banana -f cherry --colon-files date:elderberry \
--spaced-files 'fig grape' honeydew
["apple", "banana", "cherry", "date", "elderberry", "fig", "grape", "honeydew"]
Ref: https://rubyreferences.github.io/rubyref/stdlib/cli/optparse.html