views:

155

answers:

2

I'm using Perl's Getopt::Long module to parse command line arguments. However, it seems that it returns a true value even if some of the arguments are missing. Is there a way to tell if this is the case?

+3  A: 

Options are optional, hence the name 'Getopt'.

You check the option values that are set by Getopt::Long; if one of the crucial ones is 'undef', it was missed and you can identify it.

The return value tells you that there were no horrible blunders in the command line. What constitutes a blunder depends on how you use Getopt::Long, but a classic one would be that the command line contains -o output but the command does not recognize a -o option.

Jonathan Leffler
Sometimes options aren't optional.
tster
@tster: I agree; sometimes a command does require some specific option to appear - and it would be nice to be able to inform the Getopt package that such is the case. Maybe some of the other Getopt packages support that? There are plenty to choose from (and I rolled my own - but it does not support mandatory arguments). There's an argument that mandatory options should not need a minus-letter in front; they become positional arguments. However, if there are several such arguments, positional quickly becomes hard to remember.
Jonathan Leffler
+3  A: 

In plain old Getopt::Long, you can't do this directly -- as Jonathan said, you need to check your requirements for undef. However, IMHO this is a good thing -- what is a "required" parameter? Often one has parameters that are required in one case and not another -- the most common example here being the sore thumb of the --help option. It's not required, and if the user uses it, he probably doesn't know to or won't pass any of the other "required" parameters.

I use this idiom in some of my code (well, I used to, until I switched to using MooseX::Getopt):

use List:MoreUtils 'all';

Getopt::Long::GetOptions(\%options, @opt_spec);
print usage(), exit if $options{help};
die usage() unless all { defined $options{$_} @required_options;

Even with MooseX::Getopt I don't set my attributes to required => 1, again because of the --help option. Instead I check for the presence of all attributes I need before moving into the main body of program execution.

package MyApp::Prog;
use Moose;
with 'MooseX::Getopt';

has foo => (
    is => 'ro', isa => 'Str',
    documentation => 'Provides the foo for the frobnitz',
);
has bar => (
    is => 'ro', isa => 'Int',
    documentation => 'Quantity of bar furbles to use when creating the frobnitz',
);

# run just after startup; use to verify system, initialize DB etc.
sub setup
{
    my $this = shift;

    die "Required option foo!\n" unless $this->foo;
    die "Required option bar!\n" unless $this->bar;

    # ...
}
Ether