Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

use warnings => Use of uninitialized value...

by jeanluca (Deacon)
on May 24, 2006 at 08:04 UTC ( #551296=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks

Since I started to use use strict, debugging was a lot easier. However, I actually never used use warnigns. For example, I often get message like
Use of uninitialized value in regexp compilation at /usr/lib/perl5/sit +e_perl/5.8.7/myTool.pm line 143. Use of uninitialized value in pattern match (m//) at /usr/lib/perl5/si +te_perl/5.8.7/MyTool.pm line 143. Use of uninitialized value in pattern match (m//) at /usr/lib/perl5/si +te_perl/5.8.7/MyTool.pm line 143.
I don't care about uninitialized values, because thats OK. So I was wondering should I use warnings in this case or do I miss something here?

Thanks
Luca

Replies are listed 'Best First'.
Re: use warnings => Use of uninitialized value...
by davorg (Chancellor) on May 24, 2006 at 08:26 UTC

    An "uninitialised value" warning means that you tried to get data out of a variable that you hadn't put any data into. That sounds like a bug to me. Sure, it might be a pretty harmless bug and, yes, Perl will almost certainly do the right thing when faced with that situation, but it's still a bug.

    How hard would it be to fix the bug in your code? To make sure that variables that you try to get data out of have always got data in them - even if it's just an empty string.

    Personally I'd make the effort and fix the bugs. But it's your code and it's up to you (or your manager) what you do in this situation. If you want to just ignore these bugs, then you might find no warnings 'uninitialised' to be useful to you. I don't recommend it, but the functionality is there.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: use warnings => Use of uninitialized value...
by McDarren (Abbot) on May 24, 2006 at 08:13 UTC
    I guess it depends on whether or not you care about the warnings (it seems that you don't), but more importantly whether or not the rest of your code cares.

    If you're confident that it's not going to cause any unwanted side-effect, then you could probably leave them off - or better - just disable warnings for those parts of the code that are throwing them.

    Personally, I always like to produce warning-free code. Sometimes, it's just a matter of doing something like next FOO if ! defined $bar;. To me, the effort involved in that is not much more than turning warnings off/on.

    Cheers,
    Darren :)

Re: use warnings => Use of uninitialized value...
by Polonius (Friar) on May 24, 2006 at 08:30 UTC

    Luca,

    My view is that warnings are there to help you, to make you stop and think. If you really don't care about those uninitialized values, you can choose to ignore the warnings.

    But if you get into the habit (no monastic pun intended) of ignoring those warnings, if you have hundreds of "uninitialized value" warning messages scrolling up the screen, it's easy to lose something else in the middle of them. If you don't read the warnings, you might as well not display them at all.

    A quick Google turned up this thread, including the suggestion to use no warnings 'unintialized'; to suppress the warnings. That should remove the noise, so you can see the warnings you really need to see.

    Polonius
Re: use warnings => Use of uninitialized value...
by kudra (Vicar) on May 24, 2006 at 08:49 UTC
    I like to keep warnings on, because sometimes it is a bug when a variable is undefined, and I can't always rely on strict to tell me (for instance if I typo a hash key).

    Other times I expect that a variable could be undefined. In those instances, I explicitly allow for that option:

    if (defined($hash{key}) && $hash{key} =~ /\d+/) { ... }
    Other times I will set the variable to a false but defined value, such as an empty string or zero. It depends upon the context; often false and undefined are logically interchangeable, but other times they are not (in the above example, 0 has a different meaning than undef).

    It doesn't hurt to be explicit about your expectations; it can make things easier for the next person.

Re: use warnings => Use of uninitialized value...
by jeanluca (Deacon) on May 24, 2006 at 09:48 UTC
    Thanks for all the answers.
    I get the impression that it is good practice to write code that doesn't generate any warnings. In my case I do stuff like
    if ( $some_value =~ /some_thing_here/ ) { .... }
    which I should change to
    if ( defined $some_value && $some_value =~ /some_thing_here/ ) { .... }

    Luca

      That's one way to do it. Alternatively you can initialise $some_value when you define it.

      my $some_value = '';

      Or use many other techniques to ensure that it contains data before you try to use it.

      --
      <http://dave.org.uk>

      "The first rule of Perl club is you do not talk about Perl club."
      -- Chip Salzenberg

      Yeah that's the one, however the "Use of uninitialized value in regexp compilation" would indicate that you are also trying to interpolate an uninitialized variable into a regular expression either directly (e.g. something like : /$some_value/) or using the qr() mechanism, because all the warnings come from one line I would favour the former.

      /J\

Re: use warnings => Use of uninitialized value...
by liverpole (Monsignor) on May 24, 2006 at 18:44 UTC
    A true story ...

    Several weeks ago, a coworker of mine asked me to lend him my eyes to try to find a problem in a Perl script he was debugging.  Now this coworker is quite intelligent, and although, as senior architect, he's more of a C expert, and doesn't consider himself quite a Perl expert, he's fairly proficient at it.  And when I joined the company, and explained to him the wisdom of strict and warnings, he quickly agreed that their benefits outweigh any nuisance they cause, and started using them religiously in his own code.

    But this particular script did not have strict and warnings as it was inherited legacy code, and adding them would have taken time away from finding the bug, which he was anxious to fix at the particular moment.

    So the two of us narrowed it down to a place in the code where we had something like this:  (I'm paraphrasing here, not remembering the original exactly):

    # See if we need to calculate refresh matrix, based on user options if ($qeneral_user_options =~ /c/) { # This branch was NOT being taken, contrary to expectations print "Options contains 'c'\n"; calculate_refresh_matrix(); } # Debugging code added to find bug else { print "Value of \$general_user_options = '$general_user_options'\n +"; }

    and although the first branch was NOT being taken, the value of $general_user_options clearly contained the character 'c':

    Value of $general_user_options = 'cde'

    After struggling with it for more than half an hour, I finally tried editing it myself, (using vim, which I prefer over emacs), and the moment I used the '*' key to "bounce" to the next occurrence of the word "general_user_options" was when I realized, with a sinking feeling, what the problem was.  Someone had mistyped the flipping variable name... It should have been "general_user_options", but it was mistyped as "qeneral_user_options".  ... Ugh ...

    Ordinarily neither of would have created that bug, because we both use strict and warnings, but of course we inherited the script (from someone who, I'm sure, just didn't need that kind of "hand-holding", and had, in fact, introduced a number of other scoping-related issues into the code).

    So feel free to do whatever works for you.  If you've got too many warnings, and you don't want to see them, by all means turn them off if that's your style.  But I know how ridiculous it feels to miss something that miniscule, and waste a lot of time as a result, just because the usual safeguards weren't there from the beginning.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: use warnings => Use of uninitialized value...
by jeanluca (Deacon) on May 29, 2006 at 11:25 UTC
    Now that I'm using warnings (just to see what it can do for me in this particular case) I discovered some new problems which I shouldn't have discovered without warnings turned on.
    For example, I allowed a value to be used even if it were not initialized. But now I discovered situations in which this variable was undef or empty while it should have had a value.
    This runtime checking mechanism look very very useful, I'm very surprised!

    Thnx a lot
    Luca
Re: use warnings => Use of uninitialized value...
by jeanluca (Deacon) on May 24, 2006 at 10:14 UTC
    Here is a good one. When I run my program I get the following warnings:
    test 1 || Use of uninitialized value in string eq at /usr/lib/perl5/site_perl/5. +8.7/myTool.pm line 316. test 1 || Use of uninitialized value in string eq at /usr/lib/perl5/site_perl/5. +8.7/myTool.pm line 316.
    Here is the code
    read $fh, $binrec, $l ; print "test 1 |$binrec|\n" ; if ( $binrec ) { # this is line 316 print "test 2\n" ; ... }
    So, how come that there is a problem with this line ??

    luca
      The actual problem is likely in an elsif() condition. Those are lumped together at the if() line:
      use strict; use warnings; my $foo; my $bar = 1; if( $bar - 1 ) { # line 7 print $bar; } elsif( $foo - 1 ) { # throws warning -- at line 7! print "$foo\n"; my $baz = 2 * $foo; } __END__ Use of uninitialized value in subtraction (-) at - line 7. Use of uninitialized value in concatenation (.) or string at - line 10 +. Use of uninitialized value in multiplication (*) at - line 11.
      jeanluca:

      The problem is that you're using $binrec before you know if it's defined. It appears that the error occurs in your print or if statement.

      After reading read, I don't see anything that indicates that SCALAR is changed if nothing can be read due to an error. In that case, SCALAR may still be undefined. In that event, you can change the code to:

      read $fh, $binrec, $1; if (defined $binrec) { print "test 1 |$binrec|\n"; . . . } else { print 'test 2: undefined $binrec!\n'; }
      --roboticus
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://551296]
Approved by McDarren
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2021-11-27 15:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?