rubyparsingcommand-lineoptionparser

Parse multiple command line options in Ruby using OptionParser


I've just started using OptionParser for Ruby and I wanted to use flags that would use more than just one argument.

For instance, I would like to be able to run:

script --move src dst

Note how src and dst are not separated using a coma.

My initial idea was:

opts.on("-m src dst", "--move src dst ", "move file from SRCto DST") do |src|
    # do something
end

But this is not working. I assume that this is not the right approach. But how could this be done?


Solution

  • OptionParser doesn't support that; It could be patched to do so, but I'm not sure it's worth the trouble.

    Consider this code:

    require 'optparse'
    
    options = {}
    OptionParser.new do |opt|
      opt.on('-m', '--move') { |o| options[:move] = o }
    end.parse!
    
    from_name, to_name = ARGV
    
    puts "Should move: #{ options.key?(:move) }"
    puts "From: #{ from_name }"
    puts "To: #{ to_name }"
    

    Saving it and running it with various combinations of the parameters returns:

    > ruby test.rb --move from to
    Should move: true
    From: from
    To: to
    
    > ruby test.rb  from to
    Should move: false
    From:
    To:
    

    If the code is supposed to move files by default then don't bother with the --move flag, simply use:

    test.rb from to
    

    and consider removing the OptionParser block entirely.

    If the code is supposed to normally copy with the option to move, then --move becomes more sensible to act as a flag that moving is desired.

    ruby test.rb --move from to
    

    I'd have code that tests for options[:move] and run the code to move instead of copy at that point.

    In either case, the filenames shouldn't be tied to the flag, they should be supplied separately and retrieved from ARGV after OptionParser has finished parsing the command-line and removing entries it's handled.