Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Use of uninitialised value... but it is defined ?!

by seki (Monk)
on Mar 02, 2016 at 02:05 UTC ( [id://1156603]=perlquestion: print w/replies, xml ) Need Help??

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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1156603]
Approved by Lotus1
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2024-04-25 14:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found