http://qs1969.pair.com?node_id=1156603

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

Hi Monks, I got the "Use of uninitialised value" warning but the variable looks like being defined to me, so it must be a perlism that I am missing...
Maybe It is related to the closure mechanism, but in that case I do not get the point...
>perl -w test_mod.pl
Use of uninitialized value $variable in concatenation (.) or string at test_mod.pl line 12.
Use of uninitialized value $variable in say at test_mod.pl line 15. Foo::begin
test_mod.pl
use strict; use warnings; use feature 'say'; Foo->test(); { package Foo; my $variable = "bar"; BEGIN { say __PACKAGE__."::begin $variable"; } sub test { say $variable; } }
The best programs are the ones written when the programmer is supposed to be working on something else. - Melinda Varian

Replies are listed 'Best First'.
Re: Use of uninitialised value... but it is defined ?!
by AnomalousMonk (Archbishop) on Mar 02, 2016 at 03:31 UTC

    In the OPed code, the statement
        BEGIN { say __PACKAGE__."::begin $variable"; }
    refers to the lexical  $variable scalar, but the  BEGIN block executes first, after the  $variable is declared, but before it is initialized at run time. Hence, it is uninitialized, but still consistent with strict. Changing the variable name makes this clear:

    c:\@Work\Perl\monks>perl -wMstrict -le "use strict; use warnings; use feature 'say'; ;; Foo->test('xxx'); ;; { package Foo; ;; my $variable = 'bar'; ;; BEGIN { say __PACKAGE__ . qq{::begin $vaRRRRiable}; } ;; sub test { say $_[0], $_[1], $variable; } } ;; Foo->test('yyy'); " Global symbol "$vaRRRRiable" requires explicit package name at -e line + 1. BEGIN not safe after errors--compilation aborted at -e line 1.
    Changing the scalar name back to  $variable accesses the lexical again, but it's still not initialized at the time the  BEGIN block runs, nor at the first invocation of  Foo->test('xxx'); (but it is initialized by the time  Foo->test('yyy'); runs):
    c:\@Work\Perl\monks>perl -wMstrict -le "use strict; use warnings; use feature 'say'; ;; Foo->test('xxx'); ;; { package Foo; ;; my $variable = 'bar'; ;; BEGIN { say __PACKAGE__ . qq{::begin $variable}; } ;; sub test { say $_[0], $_[1], $variable; } } ;; Foo->test('yyy'); " Use of uninitialized value $variable in concatenation (.) or string at + -e line 1. Foo::begin Use of uninitialized value $variable in say at -e line 1. Fooxxx Fooyyybar


    Give a man a fish:  <%-{-{-{-<

        this kind of problems happened to me too ...

        You and me both, brother. And thank you for the compliment.


        Give a man a fish:  <%-{-{-{-<

Re:Use of uninitialised value... but it is defined ?!
by BrowserUk (Patriarch) on Mar 02, 2016 at 03:06 UTC

    BEGIN blocks run before the rest of the code in the module is even interpreted, so at the time when BEGIN { say __PACKAGE__."::begin $variable"; } runs, the lexical variable $variable has not been created, so the global variable of that name is used, and it has no value; hence the warning.

    Solution: don't close over lexical variables in BEGIN blocks.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
      lexical variable $variable has not been created, so the global variable of that name is used
      Um ,no: the BEGIN block sees the lexical var, not the package var:
      $x = 'pkg'; my $x; BEGIN { $x = 'lex' } print "$::x $x\n"; #prints pkg lex

      Dave.

        Intriguing.

        So by the time the BEGIN block runs, perl knows enough to know that there is(will be) a lexical $x, sufficient to be able to assign to it; but not enough to have initialised it.

        That's just weird!


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice.