Предполагая, что порядок запуска синтаксических анализаторов хорошо определен, вы можете просто сохранить дополнительные параметры во временной глобальной переменной и запустить OptionParser#parse!
для каждого набора параметров.
Самый простой способ сделать это - использовать разделитель, как вы намекали. Предположим, что второй набор аргументов отделен от первого разделителем --
. Тогда это будет делать то, что вы хотите:
opts = OptionParser.new do |opts|
# set up one OptionParser here
end
both_args = $*.join(" ").split(" -- ")
$extra_args = both_args[1].split(/\s+/)
opts.parse!(both_args[0].split(/\s+/))
Затем, во втором коде / контексте, вы можете сделать:
other_opts = OptionParser.new do |opts|
# set up the other OptionParser here
end
other_opts.parse!($extra_args)
В качестве альтернативы, и это, вероятно, «более правильный» способ сделать это, вы можете просто использовать OptionParser#parse
без восклицательного знака, который не удалит переключатели командной строки из массива $*
, и убедитесь, что в обоих наборах не определены одинаковые параметры. Я бы не советовал модифицировать массив $*
вручную, так как это усложняет понимание вашего кода, если вы смотрите только на вторую часть, но вы могли бы сделать это. В этом случае вам придется игнорировать недопустимые параметры:
begin
opts.parse
rescue OptionParser::InvalidOption
puts "Warning: Invalid option"
end
Второй метод на самом деле не работает, как было указано в комментарии. Однако, если вам все равно нужно изменить массив $*
, вы можете сделать это вместо этого:
tmp = Array.new
while($*.size > 0)
begin
opts.parse!
rescue OptionParser::InvalidOption => e
tmp.push(e.to_s.sub(/invalid option:\s+/,''))
end
end
tmp.each { |a| $*.push(a) }
Это больше, чем просто хакерство, но оно должно делать то, что вы хотите.