in reply to Uninitialized value ?

When you try to get a value for a key which is not in the hash, you'll get an undefined value.
That undefined value is not equal to "".
You can check undefined values with defined.

Try:

$secretword = $words{$name}; # gets secret word if (! defined $secretword) { }

Replies are listed 'Best First'.
Re: Re: Uninitialized value ?
by busunsl (Vicar) on Aug 20, 2001 at 17:46 UTC
    You fill your hash:
    %words = qw ( fred camel barney llama betty alpaca wilma alpaca );
    It now contains four elements with the names of famous actors as keys.

    If the user enters one of the keys, everything will be fine, because e.g. $words{fred} is defined, so $secretword will get the value 'camel'.
    If the user enters something, that is not in the list of keys, e.g. 'busunsl', then $words{busunsl} is not defined.
    And $secretword will become undef.

    And you check for an undef value with defined.

    You wanted to fill something into $secretword if there was nothing in it, that is, if it is undef.
    So your if-statement has to be: if (! defined $secretword) { With the ! meaning 'not'.

      This however alters the way the program works.
      if (!defined $secretword or $secretword eq '') {
      It will now both check if $secretword has some value (possible empty) and if it is empty.
      This can be boiled down to the line
      if (!$secretword) {
      or if you like the unless operator:
      unless ($secretword) {


      T I M T O W T D I
        Well, it can't be '', because it is either undef or has a value from the hash, which are all known to be not ''.
        CINE, Thks for that, learning new stuff all the time.... Steve.
Re: Re: Uninitialized value ?
by All0uette (Acolyte) on Aug 20, 2001 at 17:32 UTC
    busunsl, Thanks for that - it seems to work - although I'm still not sure why the original didn't. Especially as I got this form the book ! Any chance you can explain a lttle more. Cheers.

      I think your code should work correctly - in both versions. The only difference is that you get once a warning (which is exactly that, it's not an error) and iirc these early examples in merlyn's book (I suspect you are reading the llama) don't run under -w and strict because he hasn't introduced all the concepts yet.

      In if ($words{$name} eq "") the key $name is looked up in the hash %words. This returns undef when the key $name does not exist in %words. The undef is then compared to "" with a string compare, so the undef is transformed into the empty string. This results in the comparision being true. But this might be a source of error, so perl warns you if you have warnings enabled (-w).

      Why might that be a source of error? Well, imagine the empty string would be a valid entry in your hash, then you get the same result no matter if the key does not exist or the value is empty. Some code:

      #/usr/bin/perl -w use strict; my %hash; $hash{key1} = ""; # this produces no warning if ($hash{key1} eq "") { # true print "key1 empty!\n"; } # this produces a warning if ($hash{key2} eq "") { # true print "key2 empty!\n"; }
      to circumvent this look at defined (like suggested by busunsl) and for hashes also interesting exists.

      -- Hofmator