Israel
Israel

Reputation: 3402

Force mandatory command line argument using OptionParse in Ruby

I have this code:

options = {}
opt_parse = OptionParser.new do |opts|
  opts.banner = "Usage: example.rb [options]"

  opts.on("-g", "--grade [N]", "Grade") do |g|
    options[:grade] = g
  end

  opts.on_tail("-h", "--help", "Show this message") do
    puts opts
    exit
  end

end
opt_parse.parse!

How can I force to set -g argument? If it is not specified then trigger usage messages as would be shown if -h parameter was called.

Upvotes: 3

Views: 1578

Answers (1)

Kathryn
Kathryn

Reputation: 1607

OptionParser doesn't have a builtin way to check mandatory options. But it's easy enough to check after parsing:

if options[:grade].nil?
  abort(opt_parse.help)
end

It's relatively easy to parse the command line by hand if you aren't looking for anything too complex:

# Naive error checking
abort('Usage: ' + $0 + ' site id ...') unless ARGV.length >= 2

# First item (site) is mandatory
site = ARGV.shift

ARGV.each do | id |
  # Do something interesting with each of the ids
end

But when your options start to get more complicated, you probably will need to use an option parser such as, well, OptionParser:

require 'optparse'

# The actual options will be stored in this hash
options = {}

# Set up the options you are looking for
optparse = OptionParser.new do |opts|
  opts.banner = "Usage: #{$0} -s NAME id ..."

  opts.on("-s", "--site NAME", "Site name") do |s|
    options[:site] = s
  end

  opts.on( '-h', '--help', 'Display this screen' ) do
    puts opts
    exit
  end
end

# The parse! method also removes any options it finds from ARGV.
optparse.parse!

There's also a non-destructive parse, but it's a lot less useful if you plan on using the remainder of what's in ARGV.

The OptionParser class doesn't have a way to enforce mandatory arguments (such as --site in this case). However you can do you own checking after running parse!:

# Slightly more sophisticated error checking
if options[:site].nil? or ARGV.length == 0
  abort(optparse.help)
end

For a more generic mandatory option handler, see this answer. In case it isn't clear, all options are optional unless you go out of your way to make them mandatory.

Upvotes: 3

Related Questions