Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Preventing Use of uninitialized value

by Anonymous Monk
on Sep 20, 2021 at 19:35 UTC ( [id://11136888]=perlquestion: print w/replies, xml ) Need Help??

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

Hi there Monks!

Is there a way to prevent "Warnings" near the "ne", Use of uninitialized value in string ne at...?
In this line :
... $alldata->{ cont } ne $_->{ cont } ...

... return join '', map { my $data = join ' ', grep $_, @{ $_ }{ qw( year color age ) }; ( $alldata->{ cont } ne $_->{ cont } ) ? qq|<a href="index.pl?cont=$_->{ cont }">ALL FOUND $_->{ cont }</a> +<br>$data<br><span>$_->{ year }</span></li>| : (); } @{ $general->{ '111111' } }; ...

Thanks for looking!

Replies are listed 'Best First'.
Re: Preventing Use of uninitialized value
by pryrt (Abbot) on Sep 20, 2021 at 19:55 UTC
    Multiple methods.

    • Do error checking before that return... to prevent $alldata->{cont} and $_->{cont} from being undefined. Or use logic to make sure that if one or both are undefined, it never makes it to that line. This is the only solution that will help you discover the "why" of why the warning is occurring; the best is to prevent the data from being bad before getting here.
    • if you want to have undef ne undef to be false, then you could say $alldata->{ cont }//'<undef>' ne $_->{ cont }//'<undef>' (see choroba's reply): the defined-or operator // will stop at the first if it's defined, else use the second; by having both fall back to <undef> as the value, if both are undefined, they will resolve to the same string, and so the full expression will resolve down to '<undef>' ne '<undef>', which evaluates to false
    • if you want to have undef ne undef to be true, then you could say $alldata->{ cont }//'<undef1>' ne $_->{ cont }//'<undef2>': this time, they resolve to different strings, so the two different strings will not be equal.
    • you can say no warnings 'uninitialized'; at the smallest block, so it affects as little as possible -- I would recommend the line right before the return... line, and only if that line is somewhere in a logical block (enclosed in {}).

    The first is the best. The second and third can be used if there's some valid reason for those variables to be undefined, and you just want a known action if both are undefined. The fourth is just an indication that the programmer is unwilling to look into why the variables have undefined values, and just wants to sweep the problem under the rug and pretend there isn't a problem when there really is.


    edit: // has lower precedence than I remembered, so use parentheses as choroba shows below.

    edit2: fix typo in username (I got it right 1/2 times, so that counts for something). Thanks LanX

      Removing spaces around // doesn't change its (unfortunate) precedence. Parentheses are needed.
      ($alldata->{cont} // '<undef>') ne ($_->{cont} // '<undef>')
      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        ++Thanks. I should've tested before posting, but thought it was easy enough syntax to get without verification; my bad. (original node edited to not propagate misinformation)
Re: Preventing Use of uninitialized value
by soonix (Canon) on Sep 20, 2021 at 20:07 UTC
    Seeing the subject line "Preventing Use of uninitialized value", my first thought was
    { use warnings FATAL => qw(uninitialized); ... }
    which would ultimately prevent uninitialized values to be used :-P

    OTOH, that is not what you want, since you make clear you just don't want to be warned about it. The (short term) solution for you is simply

    { no warnings "uninitialized"; ... }
    On the third hand, of course, the best solution would be to find out, why these values are uninitialized and to do something about that… (Update: as already suggested by pryrt)
Re: Preventing Use of uninitialized value
by hippo (Bishop) on Sep 20, 2021 at 21:38 UTC

    Instead of ne you could use String::Util::neqq which would take care of that for you.

    Edit: s/Scalar/String/ - thanks, LanX


    🦛

      > you could use Scalar::Util::neqq

      Strange, the documentation says neqq($scalar1, $scalar2) The opposite of neqq ...

      On a side note: you linked to String::Util , which is not in CORE like Scalar::Util

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

Re: Preventing Use of uninitialized value
by LanX (Saint) on Sep 21, 2021 at 10:29 UTC
    it depends how you want undef ne undef to act.

    That's a conceptual question only you can answer, and Perl is right to complain about that.

    my advice is to define an extra function adjustable to exactly to the behavior you need

    • either like the neqq() hippo mentioned
    • or even better cont_links() so you can do join '', map cont_links($_), @{ $general->{ "111111" } };
    The complicated logic inside the map merits an dedicated function (plus documentation)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re: Preventing Use of uninitialized value
by NERDVANA (Deacon) on Sep 21, 2021 at 00:48 UTC

    Instead of use warnings; you could say use common::sense;

    * ducks for cover *

    ( not a serious suggestion if you develop code hat anyone else will ever contribute to, but it illustrates that some people feel strongly that undef ought to be usable in comparisons without a warning )

A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11136888]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (7)
As of 2024-04-19 10:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found