Most command line applications usually accept a variety of options that can be passed in to alter the behaviour of the application. For example, in linux, the find
command can take a -type d
option to specify only search for directories. For example the following command will find all empty directories under ~/Documents
:
find ~/Documents -type d -empty
Ruby command line applications require the same functionality and this is provided using the OptionParser
module.
So lets start off with a simple example - a Ruby command line application that politely says ‘hello’ back the user! Why not! There are several basic things we need to do to get this working:
OptionParser
module by using require 'optparse'
OptionParser
and calling on
(an alias for make_switch
) for each option we want available in our applicationon
method also in turn takes a block where we can set the variable on the hash we created earlierSo here is our first example:
require 'optparse'
class HelloParser
def self.parse(args)
options = {}
opts = OptionParser.new do |opts|
opts.on('-n', '--name NAME', 'The name of the person to say hello to') do |name|
options[:name] = name
end
end
opts.parse(args)
options
end
end
This is how to use the HelloParser class in Ruby …
options = HelloParser.parse(ARGV)
puts "Hello, #{options[:name]}" if options[:name]
… and call the application from the command line passing in the --name
(or -n
) switch
ruby optparse_example.rb --name Darren
# Outputs:
# Hello, Darren
Lets extend this basic application by introducing a second switch -t
which can indicate the number of times to say hello!
Notice the use of OptionParser::OctalInteger
in the second -t
option definition which will automatically convert the input from a String
to a Fixnum
class HelloParser
def self.parse(args)
options = {}
opts = OptionParser.new do |opts|
opts.on('-n', '--name NAME', 'The name of the person to say hello to') do |name|
options[:name] = name
end
opts.on('-t', '--times TIMES', OptionParser::OctalInteger, 'The number of times to say hello') do |times|
options[:times] = times
end
end
opts.parse(args)
options
end
end
This is how to use the HelloParser class is now used in Ruby with the extra option. Note that we use a ternary operator to consider a default value of 1 if -t
is not set.
options = HelloParser.parse(ARGV)
repeat = options[:times].nil? ? 1 : options[:times]
if options[:name]
repeat.times do
puts "Hello, #{options[:name]}"
end
end
This is how the application is run on the command line:
ruby optparse_example.rb -n Darren -t 2
# Outputs:
# Hello, Darren
# Hello, Darren
Up til now we have not considered exception handling in our application. Since we are dealing with user input we should really be considering this. The location where exceptions can occor is in the parse
method of our OptionParser
instance so lets wrap that in a begin..rescue
block as follows:
begin
opts.parse(args)
rescue Exception => e
puts "Exception encountered: #{e}"
exit 1
end
Now we should be good to go and our HelloParser
will exit gracefully if there is an error.
The OptionParser module is a great and simple way to parse parameters for Ruby command line applications. The simple DSL of make_switch
or on
are intuitive and self explainatory. Convertion of types at the parser level is also pretty handy. Next time I write a command line application in Ruby I will certainly use the OptionParser
module!
Here is Gist with the full example code.
Rotati is a full service Web and Mobile application consultancy. We use Ruby and JavaScript as our tools of choice.