in reply to Detecting an undefined hash key

You have omitted one key piece of information: how are you calling your program?

For example, do you call it with "-t" or with "-t 1"? There is a difference.

I have added some print statements to your code to help debug:

> cat 714766.pl #!/usr/bin/env perl use strict; use warnings; use Data::Dumper; use Getopt::Std; #print 'ARGV ',Dumper(\@ARGV); my $test = 1; my %opt; getopt('st',\%opt); #print 'opt ',Dumper(\%opt); if ($opt{'t'}) { $test = 1; ## testing #print "set test=1 again\n"; } elsif ($opt{'s'}) { $test = 0; ## not testing #print "set test=0\n"; } #print "test=$test\n"; if ( (!(defined($opt{'s'}))) && (!(defined($opt{'t'}))) ) { print "neither -t or -s used\n"; } else { print "either -t or -s used\n"; }

Now some sample program calls (5.8.8 on linux):

> ./714766.pl neither -t or -s used > > ./714766.pl -t neither -t or -s used > > ./714766.pl -t 0 either -t or -s used > > ./714766.pl -t 1 either -t or -s used > > ./714766.pl -s 5 either -t or -s used

Data::Dumper can help you understand what is in %opt

Update: It seems to me that the documentation for Getopt::Std is incorrect:

getopt() and getopts() will also accept a hash reference as an optional second argument. Hash keys will be x (where x is the switch name) with key values the value of the argument or 1 if no argument is specified.
If no argument is specified for getopt, the hash key is NOT set to 1 (Dumper shows it as 'undef').

Replies are listed 'Best First'.
Re^2: Detecting an undefined hash key
by LesleyB (Friar) on Oct 01, 2008 at 18:13 UTC

    Wow, wow and double wow

    It would seem that s and t are indeed strange in Getopt::Std.

    There is much for my simple mind to digest in all these replies and I thank you all for the tips and nudges on exists and Data::Dumper

    I did think that, if one expected to use -t <value> on the command line then the expected syntax for getopt would be getopt('st:',\%opt); with the : indicating a required value for the argument.

    I'll have to check the documentation on that but this did mean I thought the lack of a : would make it clear no value was being supplied for aither the s or t arguments.

      It would seem that s and t are indeed strange in Getopt::Std.
      I disagree. There is no evidence which supports the claim that s and t are strange in any way. I tried using a and b instead of s and t in my example, and the behavior is the same. Give it a try.
      I did think that, if one expected to use -t <value> on the command line then the expected syntax for getopt would be getopt('st:',\%opt); with the : indicating a required value for the argument.
      The getopts function (notice the "s" on the end) uses the ":" syntax, not the getopt function. So, it seems that, contrary to the docs, getopts requires you to supply a <value> with each switch.

        toolic, thank you for taking the time on this.

        I did cut and paste your code and uncommented the usage of Data Dumper to see what was happening.

        Using -t, I get

        ./714799.pl -t opt $VAR1 = { 't' => undef }; neither -t or -s used

        with similar results for a singular -s.

        Observe the test to see if either option had been specified fails.

        Using both -s and -t I get

        ./714799.pl -s -t opt $VAR1 = { 's' => '-t' }; either -t or -s used

        Using -a -b gives

        ./714799.pl -a -b opt $VAR1 = { 'a' => 1, 'b' => 1 }; neither -t or -s used

        and singletons of either give one hash element with the value one.

        So I still feel there is something strange about at least s and t as options for getopt.

        I read the documentation and saw that getopt and getopts appear to behave differently.

        It is mea culpa because the documentation clearly states getopt expects each switch to have an argument. Therefore -s -t should interpret -t as the argument to the -s switch (and vice versa).

        Except this doesn't appear to hold if one uses -a -b. Here the default value of 1 is used for both.

        I may try checking the rest of the alphabet on this one

        The end result is the getopts function behaves the way I originally expected getopt to behave

        Thank you once again for taking the time on this

        Update

        and

        -s and -t appear to be hungry in getopt