Parsing Command-line Options the Ruby Way (OptionParser)

An Alternative to GetoptLong

Cloud computing desk
John Lamb/Digital Vision/Getty Images

Ruby comes equipped with a powerful and flexible tool to parse command-line options, OptionParser. Once you learn how to use this, you'll never go back to looking through ARGV manually. OptionParser has a number of features that make it quite appealing to Ruby programmers. If you've ever parsed options by hand in Ruby or C, or with the getoptlong C function, you'll see how welcome some of these changes are.

  • OptionParser is DRY. You only have to write the command-line switch, its arguments, the code to run when it's encountered, and the command-line switch description once in your script. OptionParser will automatically generate help screens for you from this description, as well as infer everything about the argument from its description. For example, it will know the --file [FILE] option is optional and takes a single argument. Also, it will know that --[-no]-verbose is really two options and will accept both forms.
  • OptionParser will automatically convert options to a specific class. If the option takes an integer, it can convert any string passed on the command-line to an integer. This cuts down on some of the tedium involved in parsing command-line options.
  • Everything is very contained. All of the options are in the same place, and the effect of the option is right along-side the definition for the option. If options have to be added, changed or someone simply wants to see what they do, there is only one place to look. Once the command-line is parsed, a single Hash or OpenStruct will hold the results.

Enough Already, Show Me Some Code

So here's a simple example of how to use OptionParser. It doesn't use any of the advanced features, just the basics. There are three options, and one of them takes a parameter. All of the options are mandatory. There are the -v/--verbose and -q/--quick options, as well as the -l/--logfile FILE option. Additionally, the script takes a list of files independent of the options.

 #!/usr/bin/env ruby

 # A script that will pretend to resize a number of images

 require 'optparse'

 

 # This hash will hold all of the options

 # parsed from the command-line by

 # OptionParser.

 options = {}

 

 optparse = OptionParser.new do|opts|

   # Set a banner, displayed at the top

   # of the help screen.

   opts.banner = "Usage: optparse1.rb [options] file1 file2 ..."

 

   # Define the options, and what they do

   options[:verbose] = false

   opts.on( '-v', '--verbose', 'Output more information' ) do

     options[:verbose] = true

   end

 

   options[:quick] = false

   opts.on( '-q', '--quick', 'Perform the task quickly' ) do

     options[:quick] = true

   end

 

   options[:logfile] = nil

   opts.on( '-l', '--logfile FILE', 'Write log to FILE' ) do|file|

     options[:logfile] = file

   end

 

   # This displays the help screen, all programs are

   # assumed to have this option.

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

     puts opts

     exit

   end

 end

 

 # Parse the command-line. Remember there are two forms

 # of the parse method. The 'parse' method simply parses

 # ARGV, while the 'parse!' method parses ARGV and removes

 # any options found there, as well as any parameters for

 # the options. What's left is the list of files to resize.

 optparse.parse!

 

 puts "Being verbose" if options[:verbose]

 puts "Being quick" if options[:quick]

 puts "Logging to file #{options[:logfile]}" if options[:logfile]

 

 ARGV.each do|f|

   puts "Resizing image #{f}..."

   sleep 0.5

 end

Examining the Code

To start off with, the optparse library is required. Remember, this isn't a gem. It comes with Ruby, so there's no need to install a gem or require rubygems before optparse.

There are two interesting objects in this script. The first is options, declared at the top-most scope. It's a simple empty hash. When options are defined, they write their default values to this hash. For example, the default behavior is for this script to not be verbose, so options[:verbose] is set to false. When options are encountered on the command-line, they'll change the values in options to reflect their effect. For example, when -v/--verbose is encountered, it will assign true to options[:verbose].

The second interesting object is optparse. This is the OptionParser object itself. When you construct this object, you pass it a block. This block is run during construction and will build a list of options in internal data structures, and get ready to parse everything. It's in this block that all the magic happens. You define all the options here.

Defining Options

Each option follows the same pattern. You first write the default value into the hash. This will happen as soon as the OptionParser is constructed. Next, you call the on method, which defines the option itself. There are several forms of this method, but only one is used here. The other forms allow you to define automatic type conversions and sets of values an option is restricted to. The three arguments used here are the short form, long form, and description of the option.

The on method will infer a number of things from the long form. One thing is will infer is the presence of any parameters. If there are any parameters present on the option, it will pass them as parameters to the block.

If the option is encountered on the command-line, the block passed to the on method is run. Here, the blocks don't do much, they just set values in the options hash. More could be done, such as checking that a file referred to exists, etc. If there are any errors, exceptions can be thrown from these blocks.

Finally, the command-line is parsed. This happens by calling the parse! method on an OptionParser object. There are actually two forms of this method, parse and parse!. As the version with the exclamation point implies, it is destructive. Not only does it parse the command-line, but it will remove any options found from ARGV. This is an important thing, it will leave only the list of files supplied after the options in ARGV.

Format
mla apa chicago
Your Citation
Morin, Michael. "Parsing Command-line Options the Ruby Way (OptionParser)." ThoughtCo, Aug. 26, 2020, thoughtco.com/optionparser-parsing-command-line-options-2907753. Morin, Michael. (2020, August 26). Parsing Command-line Options the Ruby Way (OptionParser). Retrieved from https://www.thoughtco.com/optionparser-parsing-command-line-options-2907753 Morin, Michael. "Parsing Command-line Options the Ruby Way (OptionParser)." ThoughtCo. https://www.thoughtco.com/optionparser-parsing-command-line-options-2907753 (accessed March 19, 2024).