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

I've seen lots of info on how to properly get command-line _options_ (-f, --foo, etc), but not _parameters_. My script expects an e-mail address on the command-line, which I split by the '@':
#!/usr/bin/perl -w use strict; my ($username, $domain) = split(/@/, shift); if (! ($username && $dominio)) { $0 =~ s|.*/||; die("Usage: $0 <username\@domain>\n"); } # do actual stuff
However, if I call the script with no parameters, I get 2 "Use of uninitialized value" before the "Usage: ...". Is there some better way to check my commandline parameters? TIA

Replies are listed 'Best First'.
Re: Validating command-line _parameters_ (not options)
by ChemBoy (Priest) on Sep 15, 2001 at 02:32 UTC

    If @ARGV is empty, then your call to shift gives you nothing: you then use nothing as an argument to split, which (quite justifiably) complains about the uninitialized value you just fed it.

    To get around this, you could use an intermediate variable, thusly:

    my $addr = shift; unless ($addr) {die $USAGE} my ($username, $domain) = split /\@/, $addr;
    alternatively, you could simply put in an early check to see if you have the correct number of arguments:
    die $USAGE unless @ARGV == 3; #or however many args you want

    On the whole, I favor the first approach, as it lets you do a little more validation on the arguments (I sometimes just use my ($foo,$bar,$baz) = @ARGV myself), but if you're otherwise satisfied with your validation, the second method is an easy patch.

    Update: fixed foolish typo (thanks, chipmunk!).



    If God had meant us to fly, he would *never* have given us the railroads.
        --Michael Flanders

Re: Validating command-line _parameters_ (not options)
by John M. Dlugosz (Monsignor) on Sep 15, 2001 at 01:36 UTC
    Your test will look for a "false" value of either thing. That use of && itself triggers the warning! Say
    if (!defined($username) || !defined($dominio))
    for the effect you want.

    Or, I'll just report on how many arguments there are in the first place.

    if (scalar(@ARGV) != 2)
    (more often a range of legal values)

    —John

      I tried using
      if (!defined ($username) || !defined ($domain))
      But I'm still getting the same warnings.
        Maybe the split is causing the warning if ARGV[0] is undefined. Check for the presence of a parameter first!

        make sure @ARGV contains exactly one element.
        split ARGV[0] at the @
        Make sure the split gave you both parts.

Re: Validating command-line _parameters_ (not options)
by Anonymous Monk on Sep 17, 2001 at 05:38 UTC
    try checking the parameters before the split

    while (defined($ARGV[0])) { my $opt = shift; if($opt eq '-f') { my ($username, $domain) = split(/@/, shift); } else { die("Usage: <username\@domain>\n"); }a }