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

Dear Monks,

The following code is stumping me. Why does the DEFINED test come back positive in this situation? The NE test comes back as I expect but somehow it shows this as defined. Why?
my %hash = ( me => { loc = "", }, you => { loc = "", }, ); if ($hash{me}{loc} ne "") { print "location not found!"; } if (defined($hash{me}{loc})) { print "location WAS found!"; }

Replies are listed 'Best First'.
Re: Defined vs ne ""
by SuicideJunkie (Vicar) on Oct 12, 2011 at 15:01 UTC

    An empty string is quite well defined. It is a false value, but it is very much not the same as undef

      Then can you explain this?
      my $test; if (defined($test)) { print "test is defined"; } if ($test ne "") { print "test is defined again"; }
      Test comes back as undefined in this for tests. Actually the second test fails because there's an uninitialized value.

      That's partly why I have been using DEFINE because it's the only way I can get by without getting those UNDEFINED errors to make sure there is content.

      Is there a better way to see if it IS definied, meaning it contains something, so if I try to compare it to something it won't fail like the above sample I just pasted?
        It depends on whether or not you consider the empty string "something". You didn't assign anything to your test variable above, so it is undefined. But the undefined value evaluates to false in a boolean context, the empty string in a string context, and zero in numerical context (although you get an uninitialized warning in the last two with warnings on). If you want your hash values in the OP to be undefined, then assign undef instead of the empty string. Or, always initialize your variables (to the empty string if necessary), and compare to the empty string.

        Now try with my $test = '';, which is what you had in your original post.

        Perhaps you want length instead of defined.

        It seems to me that you should simply initialize your variables up front. IE: my $test = '';

        Then you don't have to worry about undefined values, and string compares with the empty string will do what you want.

Re: Defined vs ne ""
by NetWallah (Canon) on Oct 12, 2011 at 16:18 UTC
    Your code does not compile.

    Can't modify constant item in scalar assignment at test-define.pl line + 5, near ""","
    This points out the problem with your code.
    If you had used "strict" and "warnings", it would have told you:
    Bareword "loc" not allowed while "strict subs" in use at test-define.p +l line 3.
    The problem with your code is that the line should read:
    loc => "", # Your code was missing the ">", in BOTH lines where y +ou declare "loc"

                "XML is like violence: if it doesn't solve your problem, use more."