http://www.perlmonks.org?node_id=1063097

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

I have gotten a bug report containing a warning message which I am unable to explain. The code is as follows:
sub _call_hook { my $name = shift; my $file = shift; # line 123 my $detach = shift; ...
The warning is: Use of uninitialized value in scalar assignment at /usr/lib/perl5/site_perl/5.14.2/Foo/Bar.pm line 123.

_call_hook is being called as _call_hook($foo, $bar{$something}) where $bar{$something} does not exist.

Obviously, the warning is right, undef is being assigned to a scalar, but this is a pretty common case that doesn't generate a warning under normal conditions.

Could somebody shed some light on the subject? Which specific conditions may be triggering that warning?

Replies are listed 'Best First'.
Re: Unexpected warning
by cdybedahl (Acolyte) on Nov 18, 2013 at 14:48 UTC
    You get that warning on that line if $something is undefined. Although in that case you also ought to get another warning as well, about using an uninitialized value in a hash element on the calling line.
      > You get that warning on that line if $something is undefined.

      yep I can reproduce this. =)

      Seems like in the context of the call warnings were disabled.

      DB<132> use warnings; sub tst {my $a=shift, my $b =shift} DB<133> %h=() DB<134> $bla="" => "" DB<135> tst $h{$bla} => (undef, undef) DB<136> undef $bla => undef DB<137> tst $h{$bla} Use of uninitialized value in scalar assignment at (eval 81)[multi_per +l5db.pl:644] line 2.

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        I can reproduce it myself too now:
        tst(undef); # doesn't warn from tst tst($foo{undef}); # doesn't warn from tst tst($foo{$undef}); # warns from tst
        I would say this is a bug in perl, or I am missing something?

        I get no warnings from the code below:

        use strict; use warnings; sub test { my $x = shift; } my %hash = ( a => "a" ); test $hash{"b"};
      This should be pretty definitive...
      use strict; use warnings; sub tst { warn "entering tst()\n"; my $arg = shift; # line 6 warn "leaving tst()\n\n"; } my %h=(); tst $h{''}; tst $h{undef}; # line 12 my $bla=''; tst $h{$bla}; # line 14 $bla=undef; tst $h{$bla}; # line 16 undef $bla; tst $h{$bla}; # line 19
      And here's the results:
      entering tst() leaving tst() entering tst() leaving tst() entering tst() leaving tst() Use of uninitialized value $bla in hash element at perlmonks-1063097.p +l line 16. entering tst() Use of uninitialized value in scalar assignment at perlmonks-1063097.p +l line 6. leaving tst() Use of uninitialized value $bla in hash element at perlmonks-1063097.p +l line 18. entering tst() Use of uninitialized value in scalar assignment at perlmonks-1063097.p +l line 6. leaving tst()

      Turning off 'strict' has no effect, while turning off 'warnings' warnings gets rid of the messages.

      I'm actually surprised by a couple of aspects of this. First, I expected $bla=undef; tst $h{$bla} to behave the same as tst $h{undef}; it didn't. Instead, $bla=undef seems to have the same effect as undef $bla. Second, it seems that lines 16 and 19 are generating a value other than a simple undef to pass into the subroutine, otherwise the invocation in line 12 would have also generated an error in line 6.

      I get no warnings from this code below:

      use strict; use warnings; my @array; my $x = shift @array; my $y = shift @array;
Re: Unexpected warning
by MidLifeXis (Monsignor) on Nov 18, 2013 at 14:59 UTC

    Is the reporter running under perl -w? Does your module use warnings?

    --MidLifeXis