I am using Ruby OptionParser but can not figure out how to get non-option arguments as two lists.
myscript --option-one --option-two file1 file2 -- file10 file11
Is there a way to get from OptionParser two lists of files separately?
[file1, file2]
[file10, file11]
I do not care which of them remains in ARGV, just want to have two lists separately to submit them to different processing.
My current solution is
adding a handler of --
as follows
opts.on('--', 'marks the beginning of a different list of files') do
ARGV.unshift(:separator)
end
this produces ARGV with the following content
[ file1, file2, :separator, file10, file11 ]
and then, outside of OptionParser and after parse!
was called, I modify ARGV
list1 = ARGV.shift(ARGV.index(:separator))
ARGV.shift
Is there a more elegant way of accomplishing it?
You're not using OptionParser correctly. It has the ability to create arrays/lists for you, but you have to tell it what you want.
You can define two separate options that each take an array, or, you could define one that takes an array and the other comes from ARGV after OptionParser finishes its parse!
pass.
require 'optparse'
options = {}
OptionParser.new do |opt|
opt.on('--foo PARM2,PARM2', Array, 'first file list') { |o| options[:foo] = o }
opt.on('--bar PARM2,PARM2', Array, 'second file list') { |o| options[:bar] = o }
end.parse!
puts options
Saving and running that:
ruby test.rb --foo a,b --bar c,d
{:foo=>["a", "b"], :bar=>["c", "d"]}
Or:
require 'optparse'
options = {}
OptionParser.new do |opt|
opt.on('--foo PARM2,PARM2', Array, 'first file list') { |o| options[:foo] = o }
end.parse!
puts options
puts 'ARGV contains: "%s"' % ARGV.join('", "')
Saving and running that:
ruby test.rb --foo a,b c d
{:foo=>["a", "b"]}
ARGV contains: "c", "d"
You don't need to define --
. --
is handled by the shell, not the script. This is from man sh
:
-- A -- signals the end of options and disables further option processing. Any arguments after the -- are treated as filenames and arguments. An argument of - is equivalent to --.