Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

global variable initialization inside try{}

by legova (Novice)
on Apr 09, 2009 at 14:28 UTC ( [id://756613]=perlquestion: print w/replies, xml ) Need Help??

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

I have a script that calls a function in a module, and inside the module a global variable is defined. The function in the module tests the value of the global variable inside a try{} block. When the global is declared using "my", the variable is undefined inside the try{}. If I change the declaration to "our", or access the variable outside the try{} but inside in the normal scope of the function, then the variable is defined correctly. It seems like the initialization of the variable is optimized out, that the code in the try{} isn't analyzed when the function is initialized. I am trying to understand why this is the case, and whether this is expected behavior or not. Using Perl 5.8.3.

Thanks,
-Andy

Calling script:

#!/usr/bin/perl -w require "./global_stuff.pm"; global_stuff::print_global_variable();

Module: global_stuff.pm:

package global_stuff; use Error qw(:try); use strict; my $GLOBAL_VARIABLE = "IT'S WORKING FINE"; sub print_global_variable { #warn "global_variable = $GLOBAL_VARIABLE"; try { warn "global_variable = $GLOBAL_VARIABLE"; } catch Error with { }; } return 1;

Replies are listed 'Best First'.
Re: global variable initialization inside try{}
by ikegami (Patriarch) on Apr 09, 2009 at 15:39 UTC

    First, keep in mind that
    try { ... } ...
    is the same thing as
    try sub { ... }, ...
    and that's the source of many problems.

    $GLOBAL_VARIABLE falls out of scope at the end of the (.pm) file, and before 5.10.0, a reference by an anon sub isn't enough to to keep it alive.

    Simplified test case:

    use strict; use warnings; { my $f = 'test'; my $g = 'test'; sub f { sub { print "f: $f\n" }->(); } sub g { $g if 0; sub { print "g: $g\n" }->(); } } f(); g();
    >perl589\bin\perl test.pl Use of uninitialized value in concatenation (.) or string at test.pl l +ine 9. f: g: test >perl5100\bin\perl test.pl f: test g: test

    Note that adding a reference to the captured variable in the named sub — even one that's optimized away — makes it available to the anonymous sub.

    A similar problem exists with eval '$s'. While not fixed, a warning was added in 5.10.0.

    >perl589\bin\perl -wle"{ my $s='test'; sub f { print 's: ', eval '$s' +} } f()" Use of uninitialized value in print at -e line 1. s: >perl5100\bin\perl -wle"{ my $s='test'; sub f { print 's: ', eval '$s' + } } f()" Variable "$s" is not available at (eval 1) line 2. Use of uninitialized value in print at -e line 1. s:
Re: global variable initialization inside try{}
by perrin (Chancellor) on Apr 09, 2009 at 15:34 UTC
    I recommend you stop using the try{} syntax from Error, for thse reasons.
      I just read this Re: Re2: Learning how to use the Error module by example
      where it was told that the below code will leak memory
      use Error qw( :try ); sub leaky_function { my $foo = 7; try { # do something here try { $foo++; } catch Error::Simple with { # whatever }; } catch Error::Simple with { # whatever }; }
      please explain me how it leaks memory when I call it every time.

      Vivek
      -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
        In the bottom of that post it says that this leak was fixed in recent versions of perl. It used to leak by creating copies of $foo. If you're on a version prior to 5.8, you should still be concerned about it. The other problems with the try{} syntax still exist.
Re: global variable initialization inside try{}
by targetsmart (Curate) on Apr 09, 2009 at 14:50 UTC
    When the global is declared using "my", the variable is undefined inside the try{}

    It showing defined value when i checked it. my and our is not the problem here, both will be visible inside the routines of the package global_stuff if the variable is declared globally inside global_stuff, something else is the mistake check it out.

    UPDATE
    perl version 5.8.8, Error version 0.15, Debian GNU linux i686


    Vivek
    -- In accordance with the prarabdha of each, the One whose function it is to ordain makes each to act. What will not happen will never happen, whatever effort one may put forth. And what will happen will not fail to happen, however much one may seek to prevent it. This is certain. The part of wisdom therefore is to stay quiet.
Re: global variable initialization inside try{}
by JavaFan (Canon) on Apr 09, 2009 at 14:54 UTC
    Which version of Perl are you using? With 5.010, I get
    global_variable = IT'S WORKING FINE at ...
    which is just what I expect.

      ...same here (with 5.10.0), but with 5.8.8 I can reproduce the problem. (In both cases, the Error version is 0.17015.)

        I cannot reproduce the problem. Not with 5.8.8. Not with 5.8.9. And not with 5.6.2. In each case, Error version is 0.17015.
Re: global variable initialization inside try{}
by mr_mischief (Monsignor) on Apr 09, 2009 at 15:58 UTC
    I get the same issue as almut -- it works fine under 5.10.0 but under 5.8.8 there's a problem. The Error I have for my 5.10.0 is different from the one in my 5.8.8 modules. I updated Error and tried it, but to no avail.

    Update: It seems ikegami in Re: global variable initialization inside try{} has a simpler answer with no guesswork.

    I also wonder if the last to an enclosing outer loop that is found in run_clauses suffers from the same issue that redo did in 5.8.8 according to rt ticket 63752. That scoping bug left a lexical declared in the loop variant of a while loop undefined after a redo. That bug was fixed in 5.8.9 and in the 5.9.x tree for 5.10.0 so it may explain the difference in behavior. I don't have the inclination to track it down to that bug nor the skill and internals knowledge to make it easy for me to do so. I could probably muddle through, but others would have a much easier time of it.

    I'd upgrade to 5.8.9 or 5.10.0 and go from there. If the above bug is to blame, then 5.8.9 will have it fixed. We know because almut confirmed it that 5.10.0 acts as expected.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-03-29 09:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found