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

I am using Getopts to pull some command line switches. I have one optional switch, -l, that when used requires an argument. Here's my code:
$opts = getopts ('uhal:',\%Options); if ($opts) { $print_users = $Options{u}; $print_all = $Options{a}; if ($Options{l}) { $logfile=$Options{l}; } else { $logfile="$IDEAS_DIR/sec/logs/daemon.$HOSTNAME"; } if ($Options{h}) { ShowUsage(); } } else { ShowUsage() ; }
so you can see that I am using the "l:" spec to Getopts to show a required argument. When the user doesn't present an argument after -l, however, I don't see how to detect that condition (apart from another condition that might cause the Getopts call to raise an error). $Options{l} doesn't seem to get set in this case, so I can't determine for myself that "yeah they did a -l, but did no argument", and Getopts itself doesn't issue any error messages about forgetting a required argument. When the user forgets the -l argument, I'd like to tell them that they forgot it, but I don't see how I can tell without going ahead and parsing @ARGV myself .. and if I do that, why even use Getopts in the first place? Any suggestions?

Replies are listed 'Best First'.
Re: Getopts and required args
by Shendal (Hermit) on Jun 22, 2000 at 20:10 UTC
    Use Getopt::Long.

    Breifly, here's an example of what your code may end up looking like:
    use strict; use warnings; use Getopt::Long; use vars qw($opt_u $opt_h $opt_a $opt_l); &GetOptions('l=s','u','h','a') || exit 1; print "Option found: u\n" if ($opt_u); print "Option found: h\n" if ($opt_h); print "Option found: a\n" if ($opt_a); if ($opt_l) { print "Option found: l\n"; print " with value: $opt_l\n"; } else { print "You must specify -l\n"; exit 1; }
    Note that 'l=s' means that l must be specified with a value, otherwise, GetOptions() fails.

    Hope that helps,
    Shendal
      In this example, it appears that -l is a required switch, which it isn't. Or am I reading this wrong?
      if ($opt_l) { print "Option found: l\n"; print " with value: $opt_l\n"; } else { print "You must specify -l\n"; exit 1; }
      In other words, not having $opt_l should NOT be an error... only a NULL $opt_l. And in perl, is there a difference?
        Well, in my example it is required. I must have misunderstood your question. If you want to require -l to be paired with a value, but not specifying -l is okay, too, try this:

        use strict; use warnings; use Getopt::Long; use vars qw($opt_u $opt_h $opt_a $opt_l); #Note that l=s says that l requires an option # l:s means that it is optional # I have chosen the option method here so that # I can handle it how I want programatically &GetOptions('l:s','u','h','a') || exit 1; print "Option found: u\n" if ($opt_u); print "Option found: h\n" if ($opt_h); print "Option found: a\n" if ($opt_a); if (defined $opt_l) { print "Option found: l\n"; if ($opt_l) { print " with value: $opt_l\n"; } else { print " No value specified.\n"; } }
Re: Getopts and required args
by takshaka (Friar) on Jun 23, 2000 at 07:04 UTC
    die "-l requires an argument\n" if exists $Options{l} && !defined $Options{l};
      Sweet. Thanks :) I won't necessarily use "die", because I want to show the user the ShowUsage text, and I don't necessarily want to list a line number from the source. But this is what I was looking for. Thanks!
      Uh I already thanked you, but did it before I logged on (I was so anxious to try it..) ... anyway, thanks again from the "official" husker :)