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

Is it just me, or is the $result in $result= GetOptions (...option-descriptions...); of perlman:Getopt::Long not described?

Iīm searching of a way to automatically show usage information, if the user happens to give in wrong commandline options. I assumed (from experiments), that $result is the number of successfully parsed options and undef in case of a error. It is not :-(

Very (seems useless) behaviour of $result:

undef if one false input
1 if one ok input
undef if two ok inputs

??? enlighten me please

Ciao

Replies are listed 'Best First'.
Re: Getopt::Long return value
by davorg (Chancellor) on Jun 25, 2001 at 18:32 UTC

    Found this in perldoc Getopt::Long. Doesn't seem to be backed up by what you've found tho'.

    Return values and Errors

    Configuration errors and errors in the option definitions are signalled using die() and will terminate the calling program unless the call to Getopt::Long::GetOptions() was embedded in eval { ... } or die() was trapped using $SIG{__DIE__}.

    A return value of 1 (true) indicates success.

    A return status of 0 (false) indicates that the function detected one or more errors during option parsing. These errors are signalled using warn() and can be trapped with $SIG{__WARN__}.

    Errors that can't happen are signalled using Carp::croak().

    --
    <http://www.dave.org.uk>

    Perl Training in the UK <http://www.iterative-software.com>

Re: Getopt::Long return value
by Hofmator (Curate) on Jun 25, 2001 at 18:36 UTC

    My documentation says (Getopt::Long, version 2.25):

    GetOptions() will return a true value if the command line could be processed successfully. Otherwise, it will write error messages to STDERR, and return a false result.

    Give your code with some examples then we can try to figure out what went wrong ...

    -- Hofmator

Re: Getopt::Long return value
by bikeNomad (Priest) on Jun 25, 2001 at 18:42 UTC
    It will return true unless it warns you about something. However, if you've turned on permute, note that it won't warn you about options given on the command line that weren't defined (they'll just end up in @ARGV).
      This seems not to be the case. Tried to do so to achieve a "multiple GetOptions behaviour" see here.

      Bye
       PetaMem
          All Perl:   MT, NLP, NLU

Re: Getopt::Long return value
by bikeNomad (Priest) on Jun 26, 2001 at 20:21 UTC
    I don't think it's a bug.

    Here's what's happening: by default, the permute option is set to true (unless your environment variable POSIXLY_CORRECT is set). That means that option values may be mixed with non-option values (like, say, filenames). With this (default) behavior, your -h 1 -c 2 is the same as saying -h -c 2 1. In other words, if you look at @ARGV, you'll see the extra '1' argument.

    To turn this default behavior off, just do this:

    Getopt::Long::Configure('nopermute');

    . That'll make any out-of-order arguments end processing, so that -h 1 -c 2 will be parsed as  -h, and @ARGV will contain 1 -c 2. Of course, to really catch these problems, you'll have to scan @ARGV. If you don't have non-option arguments, a simple test of whether @ARGV is empty after calling GetOptions should suffice.
Re: Getopt::Long return value
by PetaMem (Priest) on Jun 26, 2001 at 00:07 UTC
    Hi, there is a simple solution:

    I have the "Programming with perl-Modules" from Patwardhan and Irving (year 1997) where this information is not present...

    #!/usr/bin/perl -w use strict; use Getopt::Long; # If it comes to parallelizing, How many processes do we allow to star +t # default is amount of CPUs on that system. May be overridden by comma +ndline my $cpu = &num_cpus; my $goback = GetOptions('cpu=i', \$cpu, 'c=i', \$cpu, 'help', \&cmdline_usage, 'h', \&cmdline_usage); print "Number of CPUs here: $cpu\n"; print "Goback was: $goback\n"; # {{{ get the number of CPUs on that system # returns: number of CPUs or 1 if no /proc/cpuinfo was found sub num_cpus { my $num_cpus = 0; my $infofile = '/proc/cpuinfo'; if($^O eq 'linux') { # Yes this is Linux we're running on if(-e $infofile) { # and cpuinfo exists open FILE, $infofile; while(<FILE>) { $num_cpus++ if(/processor/); } close FILE; } } # elsif ... your favourite OS detection routine here # If this is not a known OS we're running on ($num_cpus is then 0) # so better be careful and assume 1 CPU return $num_cpus || 1; } # }}}
    now this gives ok results *most* of the cases, but if you have commandline parameters separatedly, GetOpt silently ignores them:

    rj@proxima:~ > pxp.pl -cpu 1
    Number of CPUs here: 1
    Goback was: 1
    
    => Ok
    
    rj@proxima:~ > pxp.pl -cpu
    Option cpu requires an argument
    Number of CPUs here: 2
    Goback was:
    
    => Ok
    
    rj@proxima:~ > pxp.pl -cpu 1 -h=1
    Option h does not take an argument
    Number of CPUs here: 1
    Goback was:
    
    => Ok
    
    rj@proxima:~ > pxp.pl -cpu 1 -h 1
    Usage:
     
    -c, --cpu        set the number of CPUs (define parallelization)
    -h, --help       print this usage information
    Number of CPUs here: 1
    Goback was: 1
    
    => IMHO not Ok
    
    Ciao

    Update: The last case definitedly is not ok according to 1211. Iīm citing:

    If the option specifier is ``one:i'' (i.e. takes an optional integer argument), then the
      following situations are handled: 
    
         -one -two            -> $opt_one = '', -two is next option
         -one -2              -> $opt_one = -2
    
    Now that means it WOULD have been ok if I declared h as h:i, but I havenīt.
      What is the output when you call Getopt::Long::Configure('debug') ?

      update: fixed spelling on Configure

        Here it is:
        rj@proxima:~/proj/elric/src > pxp.pl GetOpt::Long 2.23 called from package "main". GetOptionsAl $Revision: 2.27 $ ARGV: () autoabbrev=1,bundling=0,getopt_compat=1,order=1, ignorecase=1,passthrough=0,genprefix="(--|-|\+)". => link "cpu" to SCALAR(0x8142340) => link "c" to SCALAR(0x8142340) => link "help" to CODE(0x814258c) => link "h" to CODE(0x814258c) => $opctl{"cpu"} = "=i" $opctl{"h"} = "" $opctl{"help"} = "" $opctl{"c"} = "=i"
      Why not? How else would you get a File named "1" into your script?
      I don't see what's wrong here (in the -cpu 1 -h 1 case).

      If you look at @ARGV after the GetOptions call, it should contain the argument 1.

      As the AM said, how does anyone know that the 1 is a mistaken argument? It looks like a file name to me (and to GetOptions)... what happens if you say -h 1 -cpu 1? It should complain.

        It doesnīt:

        rj@satyr: pxp.pl -h 1 -cpu 1 Usage: elric [option] -c, --cpu set the number of CPUs (define parallelization) -h, --help print this usage information Number of CPUs here: 1 Goback was: 1
        Bug here?

        Ciao