in reply to File-scoped lexicals and eval scope?

There is an implicit {} block round any file. When you use TestMeNow, the code in the file is compiled and executed, then at the end of execution, %map and $value go out of scope and are freed. Later you call initialize(), which within the eval, attempts to find the current value of $value and gets undef. In perl 5.10.0-to-be, if you enable warnings you get the following warning when that happens:
Variable "$value" is not available at (eval 1) line 1, <DATA> line 1.

Dave.

Replies are listed 'Best First'.
Re^2: File-scoped lexicals and eval scope?
by ysth (Canon) on Nov 09, 2007 at 04:51 UTC
    %map and $value go out of scope, but are not freed, since initialize closes over %map which references $value. But since the implicit file scope was exited and initialize does not close over $value, in the call to initialize, $value is no longer bound to initialize's %map's ${$map{value}} and so is "not available". Correct?

    Inserting a $value if 0; into sub initialize to make it close over $value and correcting the 'ex'/'example' inconsistency makes it work (both on 5.8.x and 5.10).

      Good analysis on what was happening to $value.

      But if the OP wants persistent, file-scope variables, I'd say that package variables are a better choice.

      Changing the 'my' to 'our' would arrange that and be more readable than relying on tricks like 'if 0', imho.

        That's the conclusion that we came to, finally, which is why the "fix" worked. It just didn't seem to be very intuitive with what we thought we knew about file-scoped lexicals. I never use package variables for this sort of thing, since those can be changed from anywhere, and I really don't like tracking down "action from a distance" issues. In this case, though, it may be the right solution. Thanks for the suggestion! Cambo
        I guess I don't consider $value if 0; a trick. The idea is that, if sub initialize wants to have its use of $value be bound to the outer lexical even after that lexical's scope is exited, it needs to explicitly mention it. scalar($value); works as well, as does 0 if $value;.  Any of them should be accompanied by a comment. If you want to be pedantic, the latter is best documented as not triggering a 'Useless use' warning.