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

Hi Monks,
I am new to Perl and I try to write scripts with "strict"...
So, I am getting this error:
Use of uninitialized value in $test

Question 1: my code still executes, so is this only a warning?
Question 2: what must I declare so that I don't get this?
Question 3: can I somehow redirect these messages to /dev/null or somewhere so that my log file doesn't get full (again, if this is not a real problem for my code)

Replies are listed 'Best First'.
Re: Can you explain this error please?
by kennethk (Abbot) on Mar 01, 2016 at 19:35 UTC

    1. This is only a warning. See warnings.

    2. In general, the solution to avoiding warnings is to follow good practice, rather than just silencing them. However, you can treat the symptom by putting
      no warnings 'uninitialized';
      before the code in question. If you provide a larger block, we can help you avoid the bad pattern.

    3. You can do all sortsa stuff, but that doesn't make it a good idea. Since this is coming out on STDERR, you can set your environment to dump all STDERR to /dev/null. You could also clobber the warning signal handler -- %SIG. But like I said, better to fix the thing that perl is complaining about than to just quiet a warning.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Can you explain this error please?
by davido (Cardinal) on Mar 01, 2016 at 22:21 UTC

    1. Yes, this is a warning. Warnings exist to alert you to potential problems. Not all warnings constitute actual critical bugs, but without investigation it's hard to know if a bug exists or not.
    2. You may remove "use warnings;", or better, declare "no warnings 'uninitialized';" in the narrowest possible scope. But this is almost always the wrong approach.
    3. Warnings are printed to STDERR. If you redirect STDERR to /dev/null you won't see any warnings, or error messages, or anything else printed to STDERR. This is probably the wrong approach. You could also define a $SIG{__WARN__} handler, which is also probably the wrong approach.

    The right approach: Determine why $test is not initialized, and either fix that, or don't use it if it's not initialized. The warning is being generated because your code encountered a case that you didn't anticipate, which left $test empty. Wouldn't you agree it is better to discover what case you didn't anticipate, and fix your code to deal with such cases more gracefully?


    Dave

Re: Can you explain this error please?
by Discipulus (Canon) on Mar 01, 2016 at 22:43 UTC
    Welcome Anonymous Monk to the wonderful world of Perl

    As you are starting learning Perl it is important that you understand what happens and why (for my little experience).

    1) yes it is only a warning and you learned how to workaround it. But don't do! You'll love how Perl trace his errors and how this helps you. Is important to be adviced about an undefined value put into a string, for example: what about the statement "My name is and i study Perl"?

    When you get a warning fix it. Notice that Perls does not complain for undefined values when you evaluate them in a boolean expression like if ($maybe_defined) {..} but it advices you if you say print "My name is $may_defined and.."

    You can easely use the || syntax or the ' ? : ' syntax (shortcut for if then else) and do something like

    print "My name is ",$may_defined||"UNDEF","and.."

    2) as already said you can declare that you do not want such category of warnings, but again don't do. In the future perahaps you can need the ability to, temporarly, disable some warnings, but dont' do it blindly.

    3) Perl sends all warnings to the third filehandle that is yet opened for you: STDERR and normally shells can tell errors from normal output. So you can redirect all warnings and errors to /dev/null or wherever you like. If it really makes sense in your application do it.

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Can you explain this error please?
by FreeBeerReekingMonk (Deacon) on Mar 01, 2016 at 19:39 UTC
    Perl features Autovivification, which means that a variable that has no initial value is being used in a comparison, string concatenation, numerical operation, etc. Perl then replaces the variable with "" or 0 depending on what you are trying to do. Usually it means you have a typo in a variable, so $my_value and somewhere you may have used $my_alue. Or you do my $temp instead of my $temp = 0;

    To isolate where the problem is occurring, try adding a block with the no warnings pragma:

    use warnings; use strict; my $a = 5; { no warnings; # remove to see what happens print $a + $b; }

      Autovivification is when perl creates records in a hash or array after dereferencing an undef. What you are describing is simply that an undef in string context is rendered as the empty string, just like an undef in numeric context is 0 and an undef in logical context is false.

      When turning off warnings, you should turn off the minimal set for your target scenario, e.g.

      { no warnings 'uninitialized'; # remove to see what happens print $a + $b; }
      Usually it means you have a typo in a variable,
      Except the OP said they have strict enabled, so in that scenario they would get a fatal error, not a warning. Which is why I asked the OP for a larger block of code to inform context.

      #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.