harpreetsammi has asked for the wisdom of the Perl Monks concerning the following question:

Hi Experts,

I am running a perl script which uses GetOpt::Long

giveinfo.pl -name mike -long

where, -name option ("name=s") needs a mandatory string argument

-long is optional flag if set, will provide more details of the user named mike

If i miss the user name while running giveinfo.pl as below then it does not error out -

giveinfo.pl -name -long

In this case, its treating -long as user name and DOES NOT error out. I want that in above case it should error out and say "Option name requires an argument".

FYI. in the below scenario it error out as expected if i use -name at the end of command line -

giveinfo.pl -long -name Option name requires an argument

Can someone please help how can i error out correctly in the below scenerio which is missing name mike -

giveinfo.pl -name -long

I don't want to use "=" as -

giveinfo.pl -name= -long

Thanks and Regards,

Harry

Replies are listed 'Best First'.
Re: Getopt::Long treating option as an argument
by Athanasius (Archbishop) on Dec 16, 2014 at 16:12 UTC

    Hello harpreetsammi, and welcome to the Monastery!

    You can use a subroutine to validate the argument. For example:

    #! perl use strict; use warnings; use Getopt::Long; my ($name, $long); GetOptions ( 'name=s' => \&name_handler, long => \$long, ) or die "Error in command line arguments\n"; printf "Name is '%s', long is %s\n", $name, $long ? 'set' : 'not set'; sub name_handler { my (undef, $n) = @_; if ($n =~ /^--/) { die "Option 'name' requires an argument\n"; } else { $name = $n; } }

    Output:

    2:11 >perl 1098_SoPW.pl --name Fred --long Name is 'Fred', long is set 2:11 >perl 1098_SoPW.pl --name --long Option 'name' requires an argument Error in command line arguments 2:11 >

    See Getopt::Long#User-defined-subroutines-to-handle-options.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      You can insert this line after GetOptions() to set up the default value if neccessary.
      $name ||= 'default_name';
Re: getopt::long treating option as an argument
by toolic (Bishop) on Dec 16, 2014 at 16:52 UTC
    Thanks for pointing this out! Much of my code uses =s, and I now realize I have bugs. However, upon closer inspection of Getopt::Long, it is documented:
    = type [ desttype ] [ repeat ] The option requires an argument of the given type. Supporte +d types are: s String. An arbitrary sequence of characters. It is vali +d for the argument to start with "-" or "--".

    Note that it is much less likely (or impossible?) to happen with =i or =f.

    For those who store options in a hash, Athanasius' handler approach doesn't apply directly. Here is an equivalent:

    use warnings; use strict; use Getopt::Long qw(GetOptions); my %opt; GetOptions(\%opt, qw(name=s long)) or die; if ( (exists $opt{name}) and ($opt{name} =~ /^-/) ) { die "Option name requires an argument\n"; }

    or, more generally...

    my %opt; my @string_opts = qw(name foo|goo bar); GetOptions(\%opt, qw(help long), map { "$_=s" } @string_opts) or die; for my $oname (@string_opts) { $oname = (split /\|/, $oname)[0]; # handle alternate names if ( (exists $opt{$oname}) and ($opt{$oname} =~ /^-/) ) { die "Option $oname requires an argument\n"; } }