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

My Win32 Perl/Tk code looks a bit like this:

use warnings; my $Timer; my $Display; # This is the Canvas where the widgets are drawn {main code skipped over} sub showProblem { $Timer = $Display->after(shift, sub { $Globalvariable = blah blah blah... $Timer->cancel(); }); }

I get a warning
Variable "$Globalvariable" may be unavailable at some line number...

It seems that putting the global in an anonymous sub is a problem here, although warning aside, the code works perfectly. Yet I have other cases (with the same variable) where Warnings does not complain. Further, if there are two references to $Globalvariable in the anonymous sub, the second one does not generate a warning.

Any clue as to why this might be? I can eliminate the message by the use of "no warnings" in the anonymous sub, but I'm still confused by why I would need to do this. What is the Warnings pragma trying to tell me that I am too stupid to see?

Please educate me...

Nat

Replies are listed 'Best First'.
Re: Help with 'use Warnings' please?
by davorg (Chancellor) on Jul 13, 2009 at 15:47 UTC

    There's quite a bit of important code missed out of your example, so it's hard to know exactly what's going wrong. Using strict as well as warnings would probably help.

    Sounds like it's some kind of scoping issue in your closure. Try adding use diagnostics to your code and see if that gives more detail.

    --

    See the Copyright notice on my home node.

    Perl training courses

      Using strict as well as warnings would probably help.
      Looking at perldiag at the entry for the warning which is closest what is quoted by the OP, using strict would not help. In fact, it can only happen with lexicals - it shouldn't happen with package variables.
      I could have posted the entire example, but it would have been much too long. I am using strict, and the code I posted does in fact show pretty much exactly what is going on.

      I will experiment with 'use diagnostics' and see what that reveals. Thanks for the suggestion.

      Nat

        I could have posted the entire example, but it would have been much too long. I am using strict, and the code I posted does in fact show pretty much exactly what is going on.

        The best way to get help here is to post a self-contained program which exhibits your problem. If we can run your program, then it's far more likely that we'll be able to find the issue.

        I find that in the process of cutting a program down to an example that illustrates a particular problem, it often gives me a different perspective and enables me to find a solution without even posting here.

        --

        See the Copyright notice on my home node.

        Perl training courses

Re: Help with 'use Warnings' please?
by JavaFan (Canon) on Jul 13, 2009 at 15:55 UTC
    I guess the warning you were getting was Variable "$Globalvariable" is not available. If you look in the perldiag manual page, you see an explaination of what is happening (look for the first reason). You should then be able to fix it.
      I looked at the page mentioned, and I guess I'm too dense today to get it. The explanation of "An inner (nested) anonymous subroutine is inside a named subroutine, and outside that is another subroutine; and the anonymous (innermost) subroutine is referencing a lexical variable defined in the outermost subroutine." doesn't grok because the only outer sub is the main program.

      The anonymous sub is indeed inside a named sub, it is true, but there is no "outer" sub, unless the main program counts. I also do not see how the anonymous sub could be called when "the outermost sub is not active" since the only possible way to get there is via the named sub. I guess my ignorance is showing.

      I tried changing the anonymous sub to a named sub, but that breaks the code in other ways. Fixes are possible, but the code then becomes a fair bit more complex, so IMHO this warning is simply bogus and should just be ignored.

      So, is there a better fix, or is a permanent 'no warnings' in the anonymous sub the way to go?

      Nat

        Did you try making $GlobalVariable a package variable?