In a previous article we discussed how to parse command-line options with Ruby's default OptionParser class. While this does work quite well, it's quite verbose. Just defining four options will require 20 or so lines of code, and this is not ideal. It also requires you to remember how to use OptionParser, which is not something you may use regularly.
Trollop is a great library (if you ignore the clever but inappropriate name) that solves these problems. It aims to make option parser easy and just get out of your way. It's a small single-file library that you can take with you in your lib directory. It also aims to require only one or two lines per command line option and it's almost impossible to forget how to use.
Trollop is a simple gem with no native dependencies. Install it as you would any other gem.
$ sudo gem install trollop
Once installed, you may want to copy trollop.rb from your gems directory to your project's lib directory if you'd prefer to require it that way.
Alternatively, you can just download it as instructed on the Trollop homepage and skip Rubygems altogether.
Trollop is extremely easy to use. It's best explained by showing you some code first.
#!/usr/bin/env ruby require 'rubygems' require 'trollop' # Dummy download method, returns random true/false def download( url, user_agent ) [ true, false ][rand(2)] end opts = Trollop::options do opt :url, "URL to download", :required => true opt :retry, "Retry if download failed", :default => false opt :delay, "Delay between retries", :default => 15 opt :user_agent, "User Agent string to use", :type => :string end while true do res = download( opts[:url], opts[:user_agent] ) puts "Error" unless res break if res || !opts[:retry] sleep opts[:delay] end
As you can see, all of the options are stored in an object called (in this example) opts. Within the block you pass to the Trollop::options method, you define options using a small domain-specific language. Each option is defined using the opt method, which takes at a minimum the option's name and a short description. If desired, you could also pass as default value, the short form or the type.
Another thing you'll notice is that option definition is option parsing invocation. There's no second step there. It will automatically take what you defined, parse ARGV with it and return a hash of the options. Just another step you don't have to do.
In fact, there are only six options you can define for each option. They are:
:long - Manually specify the long version of the argument. This is usually unnecessary as it will automatically derive a long version of the argument from the first parameter to opt.
:short - Specify a short version of the argument. Again, this is automatically derived from the name you gave it, so you don't usually have to set this.
:type - Specify which type the option's argument is. This will usually be something like :string or :int. Options are :flag type by default, and don't take arguments. If you specify a :default option, :type is unnecessary.
:default - Specify a default value that will be used if the option is not supplied by the user.
:required - If the option is not supplied by the user, die with an error message.
:multi - Multiple instances of this option are allowed on the command line. For example, the user could say myprog -f file1 -f file2.