Using OptionParser to Parse Commands in Ruby

A businessman with a notebook

TongRo Images/Getty Images

In the article discussing OptionParser's features we discussed some of the reasons that make using OptionParser in Ruby preferable to looking through ARGV manually to parse commands by hand. Now it's time to get down to learning how to use OptionParser and its features.

The following boilerplate code will be used for all the examples in this tutorial. To try any of the examples, simply put the example's opts.on block next to the TODO comment. Running the program will print the state of the options has and ARGV, allowing you to examine the effects of your switches.

#!/usr/bin/env ruby
require 'optparse'
require 'pp'
# This hash will hold all of the options
# parsed from the command-line by
# OptionParser.
options = {}
optparse = OptionParser.new do|opts|
# TODO: Put command-line options here
# 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!
pp "Options:", options
pp "ARGV:", ARGV

Simple Switch

A simple switch is an argument with no optional forms or no parameters. The effect will be to simply set a flag in the options hash. No other parameters will be passed to the on method.

options[:simple] = false
opts.on( '-s', '--simple', "Simple argument" ) do
options[:simple] = true
end

Switch with Mandatory Parameter

Switches that take a parameter only need to state the parameter name in the long form of the switch. For example, "-f", "--file FILE" means the -f or --file switch takes a single parameter called FILE, and this parameter is mandatory. You cannot use either -f or --file without also passing it a parameter.

options[:mand] = ""
opts.on( '-m', '--mandatory FILE', "Mandatory argument" ) do|f|
options[:mand] = f
end

Switch with Optional Parameter

Switch parameters don't have to be mandatory, they can be optional. To declare a switch parameter optional, place its name in brackets in the switch description. For example, "--logfile [FILE]" means the FILE parameter is optional. If not supplied, the program will assume a sane default, such as a file called log.txt.

In the example, the idiom a = b || c is used. This is just shorthand for "a = b, but if b is false or nil, a = c".

options[:opt] = false
opts.on( '-o', '--optional [OPT]', "Optional argument" ) do|f|
options[:opt] = f || "nothing"
end

Automatically Convert to Float

OptionParser can automatically convert argument to some types. One of these types is Float. To automatically convert your arguments to a switch to Float, pass Float to the on method after your switch description strings.

Automatic conversions are handy. Not only do they save you the step of converting the string to the desired type, but also check the format for you and will throw an exception if it is formatted incorrectly.

options[:float] = 0.0
opts.on( '-f', '--float NUM', Float, "Convert to float" ) do|f|
options[:float] = f
end

Some other types that OptionParser can convert to automatically include Time and Integer.

Lists of Arguments

Arguments can be interpreted as lists. This can be seen as converting to an array, as you converted to Float. While your option string can define the parameter to be called "a,b,c", OptionParser will blindly allow any number of elements in the list. So, if you need a specific number of elements, be sure to check the array length yourself.

options[:list] = []
opts.on( '-l', '--list a,b,c', Array, "List of parameters" ) do|l|
options[:list] = l
end

Set of Arguments

Sometimes it makes sense to restrict arguments to a switch to a few choices. For example, the following switch will only take a single mandatory parameter, and the parameter must be one of yes, no or maybe. If the parameter is anything else at all, an exception will be thrown.

To do this, pass a list of acceptable parameters as symbols after the switch description strings.

options[:set] = :yes
opts.on( '-s', '--set OPT', [:yes, :no, :maybe], "Parameters from a set" ) do|s|
options[:set] = s
end

Negated Forms

Switches can have a negated form. The switch --negated can have one that does the opposite effect, called --no-negated. To describe this in the switch description string, place the alternative portion in brackets: --[no-]negated. If the first form is encountered, true will be passed to the block, and false will be blocked if the second form is encountered.

options[:neg] = false
opts.on( '-n', '--[no-]negated', "Negated forms" ) do|n|
options[:neg] = n
end
Format
mla apa chicago
Your Citation
Morin, Michael. "Using OptionParser to Parse Commands in Ruby." ThoughtCo, Aug. 26, 2020, thoughtco.com/using-optionparser-2907754. Morin, Michael. (2020, August 26). Using OptionParser to Parse Commands in Ruby. Retrieved from https://www.thoughtco.com/using-optionparser-2907754 Morin, Michael. "Using OptionParser to Parse Commands in Ruby." ThoughtCo. https://www.thoughtco.com/using-optionparser-2907754 (accessed April 26, 2024).