Getopt modules 08: Getopt::Tiny

About this mini-article series. Each day for 24 days, I will be reviewing a module that parses command-line options (such module is usually under the Getopt::* namespace). First article is here.

Getopt::Tiny is a module written in 1999-2002 by David Muir Sharnoff (MUIR). David is a veteran Perl programmer who also programs in several other languages like Go, Python, node, Java. This module is admittedly among his earlier works, and the age shows e.g. it only recognizes “old” style long option with a single dash prefix (-foo) instead of “new” one with double dash prefix (--foo). But there are a couple of things I want to highlight.

Getopt::Tiny is not a Getopt::Long wrapper; it implements its own parsing. The code is short and simple, as the name ::Tiny would suggest, at around only 115 lines. It currently does not have any CPAN distributions depending on it.

The feeling that I get looking at this module is that it tries to be less redundant than Getopt::Long. For example, instead of option spec being something like name=s or name=s@ or name=s%, this module guesses the destination type from the type of references the option is paired with:

    opt1 => \$str,  # a scalar/string
    opt2 => \@ary,  # an array
    opt3 => \%hash, # a hash

Getting a bit quirky, when generating usage message, instead of letting user specify a summary string like some other modules (e.g. Getopt::Long::Descriptive, Getopt::Simple, Getopt::Long::More) or by extracting POD like some (e.g. Getopt::Euclid, Getopt::Declare) this module searches from comment in source code. The comment must be particularly formatted, i.e.:

# begin usage info
my %flags = (
    opt1 => \$str,  # description for opt1
    opt2 => \@ary,  # description for opt2
    opt3 => \%hash, # description for opt3
my %switches = (
    switch1 => \$switch1,  # description for switch1
# end usage info
getopt(\@ARGV, \%flags, \%switches);

Another rather quirky thing, also as the result of trying (a bit too hard) to be compact, the fourth option to its getopt() option is a string that will be used in the usage message for symbolizing the arguments, e.g. “files”, which will generate a usage message e.g.:

Usage: myprog [flags] [switches] files

This means, it’s okay if @ARGV contains arguments after the options (flags, switches) have been stripped, e.g.:

% myprog --opt1 val --opt2 val --opt2 val foo bar

But, if the fourth argument is not specified, the usage message is simply:

Usage: myprog [flags] [switches]

And the command-line is not allowed to have extra arguments (foo, bar). On the other hand, there’s no way to express that command-line arguments are required. Or whether a flag is required. Or default value.

But at least the code is compact as well as very straightforward, which is better than some other modules that I looked at.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s