rubyargumentsoptionparser

How do you specify a required switch (not argument) with Ruby OptionParser?


I'm writing a script and I want to require a --host switch with value, but if the --host switch isn't specified, I want the option parsing to fail.

I can't seem to figure out how to do that. The docs seem to only specify how to make the argument value mandatory, not the switch itself.


Solution

  • I am assuming you are using optparse here, although the same technique will work for other option parsing libraries.

    The simplest method is probably to parse the parameters using your chosen option parsing library and then raise an OptionParser::MissingArgument Exception if the value of host is nil.

    The following code illustrates

    #!/usr/bin/env ruby
    require 'optparse'
    
    options = {}
    
    optparse = OptionParser.new do |opts|
      opts.on('-h', '--host HOSTNAME', "Mandatory Host Name") do |f|
        options[:host] = f
      end
    end
    
    optparse.parse!
    
    #Now raise an exception if we have not found a host option
    raise OptionParser::MissingArgument if options[:host].nil?
    
    
    puts "Host = #{options[:host]}"
    

    Running this example with a command line of

    ./program -h somehost
    

    simple displays "Host = somehost"

    Whilst running with a missing -h and no file name produces the following output

    ./program:15: missing argument:  (OptionParser::MissingArgument)
    

    And running with a command line of ./program -h produces

    /usr/lib/ruby/1.8/optparse.rb:451:in `parse': missing argument: -h (OptionParser::MissingArgument)
      from /usr/lib/ruby/1.8/optparse.rb:1288:in `parse_in_order'
      from /usr/lib/ruby/1.8/optparse.rb:1247:in `catch'
      from /usr/lib/ruby/1.8/optparse.rb:1247:in `parse_in_order'
      from /usr/lib/ruby/1.8/optparse.rb:1241:in `order!'
      from /usr/lib/ruby/1.8/optparse.rb:1332:in `permute!'
      from /usr/lib/ruby/1.8/optparse.rb:1353:in `parse!'
      from ./program:13