Command Line Options Parsing in Ruby
One of the most common ways how to control a command line application is to use options, e.g. almost every command line application would understand -h
or --help
or /?
(common in the MS-DOS world) as a request to show some instruction.
Ruby (but also other programming languages such as Java) has a basic support for accessing command line arguments, so there is a space for libraries that make reading options easier such as Trollop, Optiflag or Choice.
Update: Actually not so true for Ruby – there are two standard libraries (they are built-in, so it is not necessary to install them): OptionParser and GetoptLong. Check them out. (thnx to Max)
The Choice library is an interesting choice, not only because it works smoothly, but it is a nice example of a domain specific language (DSL or see my older post about DSL in Ruby).
I. ARGV
Firstly an example how to read command line arguments in Ruby. It is using the standard ARGV array that holds all arguments that were specified after the application name:
ARGV.each do |a| puts "Argument: #{a}" end
Store it into a file, e.g. argv_example.rb
.
Let’s try it with three arguments:
ruby argv_example.rb 1 abcd 3
and the output should be:
Argument: 1 Argument: abcd Argument: 3
It works ok for position based options, that is enough for simple applications, but if we would like to support multiple options distinguished by labels (or switches, e.g. -h
) that order and number may vary, it would be quite cumbersome to support it with the functionality provided by ARGV.
II. Choice
Choice is a gem, that is necessary to install:
sudo gem install choice
As already mentioned, options are defined in Choice in its own DSL that is really easy to understand way. It supports for each option short and long switches, description, default value, if it is required and a lot more.
Let’s create an application that has the title and footer options and supports common options like help and version:
require 'rubygems' require 'choice' Choice.options do header 'Application options:' separator 'Required:' option :title, :required => true do short '-t' long '--title=TITLE' desc 'The document title.' end separator 'Optional:' option :footer do short '-f' long '--footer=FOOTER' desc 'The document footer.' default 'Standard footer' end separator 'Common:' option :help do short '-h' long '--help' desc 'Show this message.' end option :version do short '-v' long '--version' desc 'Show version.' action do puts 'ChoiceExample version 1.0' exit end end end puts "Creating document with title '#{Choice.choices.title}' and footer '#{Choice.choices[:footer]}'"
and store it into a file, e.g. choice_example.rb
.
All options and their values are accessible through Choice.choices.OPTION
, Choice.choices[:OPTION]
or Choice.choices['OPTION']
in an application.
Choice provides generating of the usage instructions for free :)
ruby choice_example.rb -h
shows
Usage: choice_example.rb [-tfhv] Application options: Required: -t, --title=TITLE The document title. Optional: -f, --footer=FOOTER The document footer. Common: -h, --help Show this message. -v, --version Show version.
Various ways of calling the application
ruby choice_example.rb -t "My document" -f "Page: 1/1"
or
ruby choice_example.rb -f "Page: 1/1" --title "My document"
means no complication for the application and generates the same result:
Creating document with title 'My document' and footer 'Page: 1/1'
Enjoy --smile