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

In a while loop reading lines from $FH, I get error:

Use of uninitialized value in string eq at file.pm line 103

My code is this:

100 if ( !defined( $data->{$id}{'HOST'} ) ) { 101 printf("no HOST defined at data->{%s}\n", $id); 102 } 103 if ($data->{$id}{'HOST'} eq "" ) { 104 # do this 105 } else { 106 # do that 107 }

I don't see the output from line 101 so there must be something in $data->{$id}{'HOST'}, correct?
So how can I possibly get the error from line 103 then?

Replies are listed 'Best First'.
Re: if not defined question (indeed)
by tye (Sage) on Sep 10, 2014 at 04:06 UTC

    Indeed, based on the code you show, you should not be able to get the warning you show without also getting your "no HOST defined ..." message. Now, there are (unlikely) ways I can imagine arranging that to happen: 1) have STDOUT going to /dev/null but not STDERR; 2) override printf() with something that changes $_[1]; etc.

    My guess is that a more likely explanation is that this isn't the exact code that you are dealing with and your translation from the real code to this post omitted the real cause.

    BTW, I disagree with most of the other replies offered so far. Autovivification doesn't explain your problem. I think using exists is a worse idea (only use exists when you have a separate useful meaning for "exists but not defined", which is almost never the case, and should almost never be the case), and suggesting that you change the flow just seems to be missing the point that you are trying to figure out how you got the warning in question.

    - tye        

Re: if not defined question
by LanX (Saint) on Sep 09, 2014 at 21:41 UTC
    A) why don't you dump the content to find out?

    B) why don't you use else in 103 ?

    C) probably the entry doesn't exist?

    D) try to avoid autovivification in 100 if you are not sure about the existence of nested entries!

    Cheers Rolf

    (addicted to the Perl Programming Language and ☆☆☆☆ :)

    update
    Can't test but looks like autovivification of $id is the problem.
Re: if not defined question
by GrandFather (Saint) on Sep 09, 2014 at 22:31 UTC

    The test at line 100 doesn't prevent line 103 executing. Maybe you want to bail (use return, die or exit as appropriate) after the print at line 101?

    Perl is the programming world's equivalent of English
Re: if not defined question
by Anonymous Monk on Sep 09, 2014 at 21:51 UTC
    Dive of Data::Diver does not autovivify
    use Data::Diver qw/ Dive /; ... my $val = Dive( $data, \$id, \'HOST' ); if( !defined $val ){ ... }
Re: if not defined question
by roboticus (Chancellor) on Sep 09, 2014 at 23:43 UTC

    Meh, ignore me.

    That just shows that $data->{$id}{HOST} exists, but has an undefined value. This little bit should help sort things out for you. I'm thinking maybe you have a case similar to GONE.

    $ cat t.pl use strict; use warnings; my $data = { FOO=>{HOST=>undef, BANG=>3}}; for my $K (qw(HOST BANG GONE)) { print "$K exists\n" if exists $data->{FOO}{$K}; print "$K defined\n" if defined $data->{FOO}{$K}; print "$K val==''\n" if $data->{FOO}{$K} eq ""; } $ perl t.pl HOST exists Use of uninitialized value in string eq at t.pl line 9. HOST val=='' BANG exists BANG defined Use of uninitialized value in string eq at t.pl line 9. GONE val==''

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: if not defined question
by Anonymous Monk on Sep 10, 2014 at 01:56 UTC
    Suggest using exists() ... but unless you are certain that an entry for $id exists at this point do not assume that it does; you should check both.