Question

I'm trying to pick up ruby by porting a medium-sized (non-OO) perl program. One of my personal idioms is to set options like this:

use Getopt::Std;
our $opt_v;  # be verbose
getopts('v');
# and later ...
$opt_v && print "something interesting\n";

In perl, I kind of grit my teeth and let $opt_v be (effectively) a global.

In ruby,the more-or-less exact equivalent would be

require 'optparse'
    opts.on("-v", "--[no-]verbose", TrueClass, "Run verbosely") {
        |$opt_verbose|
    }
    opts.parse!
end

where $opt_verbose is a global that classes could access. Having classes know about global flags like that seems ... er ... wrong. What's the OO-idiomatic way of doing this?

  • Let the main routine take care of all option-related stuff and have the classes just return things to it that it decides how to deal with?
  • Have classes implement optional behaviour (e.g., know how to be verbose) and set a mode via an attr_writer sort of thing?

updated: Thanks for the answers suggesting optparse, but I should have been clearer that it's not how to process command-line options I'm asking about, but more the relationship between command-line options that effectively set a global program state and classes that should ideally be independent of that sort of thing.

Was it helpful?

Solution

A while back I ran across this blog post (by Todd Werth) which presented a rather lengthy skeleton for command-line scripts in Ruby. His skeleton uses a hybrid approach in which the application code is encapsulated in an application class which is instantiated, then executed by calling a "run" method on the application object. This allowed the options to be stored in a class-wide instance variable so that all methods in the application object can access them without exposing them to any other objects that might be used in the script.

I would lean toward using this technique, where the options are contained in one object and use either attr_writers or option parameters on method calls to pass relevant options to any additional objects. This way, any code contained in external classes can be isolated from the options themselves -- no need to worry about the naming of the variables in the main routine from within the thingy class if your options are set with a thingy.verbose=true attr_writer or thingy.process(true) call.

OTHER TIPS

The optparse library is part of the standard distribution, so you'll be able to use it without requiring any third party stuff.

I haven't used it personally, but rails seems to use it extensively and so does rspec, which I guess is a pretty solid vote of confidence

This example from rails' script/console seems to show how to use it pretty easily and nicely

The first hit on google for "processing command line options in ruby" is an article about Trollop which seems to be a good tool for this job.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top