Now I am wondering if the key factor for Perl retaining the state of %webpaths is due specifically to the precedence of calls in testme.pl to subs defined in DataBank.pm, ...
Yes, that's it (I assume you meant s/precedence/presence/). From Persistent variables with closures:
Unlike local variables in C or C++, Perl's lexical variables don't necessarily get recycled just because their scope has exited. If something more permanent is still aware of the lexical, it will stick around. So long as something else references a lexical, that lexical won't be freed--which is as it should be. You wouldn't want memory being free until you were done using it, or kept around once you were done. Automatic garbage collection takes care of this for you. ... If declared at the outermost scope (the file scope), then lexicals work somewhat like C's file statics. They are available to all functions in that same file declared below them, but are inaccessible from outside that file. This strategy is sometimes used in modules to create private variables that the whole module can see.
That "something more permanent" are the subs, and I'll get more into why those are "more permanent" below.
... and will therefore persist while testme.pl stays alive, even though other modules which altered the state of %webpaths are themselves long dead?
Well, obviously it's a bit more complicated than "dead" and "alive" :-) Especially in dynamic languages like Perl, where the lines between the traditional "compile time" and "run time" can be blurred - you can run code at compile time with BEGIN and use, and compile code at runtime with eval, do, and require. In this case, consider what is going on when you write use DataBank; (or in your case use Importer 'DataBank';, which as I understand it is equivalent): During the compliation of testme.pl, when the compiler encounters the line use DataBank;, basically it will immediately compile and execute all of the code in DataBank.pm (plus the import/export code, the details of which I'll skip over for now), so when the line use DataBank; finishes compiling, the code in DataBank.pm will have finished executing (and all of its scopes have ended).
Now the code in DataBank.pm includes statements like sub set_webpath { ... }. The important thing to keep in mind is that this does not actually run the code inside the sub, all it does is install that code into the symbol table under the names &DataBank::set_webpath and via the import/export mechanism also as &main::set_webpath, so that it can be run later, when other code says set_webpath(...). So I hope it's obvious that the subs from DataBank.pm need to stick around until after it has finished compiling and executing, because otherwise testme.pl couldn't call those functions, and the entire concept of modules exporting functions would break down. And since those functions need the %webpaths variable, it makes sense to keep that around as well, as described above.
In reply to Re^3: modular file scoping
by haukex
in thread modular file scoping
by Pstack
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |