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!
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 | [reply] [d/l] [select] |
|
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]
| [reply] [d/l] [select] |
|
++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)
| [reply] |
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) | [reply] [d/l] [select] |
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
| [reply] [d/l] [select] |
|
> 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
| [reply] [d/l] |
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)
| [reply] [d/l] [select] |
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 )
| [reply] [d/l] [select] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
|
|