Your skill will accomplish what the force of many cannot |
|
PerlMonks |
What can we assume in a BEGIN block ?by leriksen (Curate) |
on Oct 04, 2004 at 08:31 UTC ( [id://396149]=perlquestion: print w/replies, xml ) | Need Help?? |
leriksen has asked for the wisdom of the Perl Monks concerning the following question:
Brother Monks,
My question is 'what parts of your code can you assume have already been parsed when you are writing a BEGIN block ?' I ask because I spent quite some time on the weekend struggling with a package global, set in a BEGIN block, getting clobbered at run time for reasons that are still a little unclear.
Background : I am refactoring some modules, one of which pulls in a configuration file at compile time. That is, clients of this module use it thus
In Config.pm, the code was originally like this
This worked, but I changed the $initialised from a my to an our so that there was a way to reload a config file if required (I've changed this to a Reload() method now) And because I wanted to make clearer that the call to _initialise() was a deliberate decision, I put it in a BEGIN {} block - to me it stands out a lot clearer that the bare statement in the original. So we have
Now because I like writing correct code, I wrapped all this in a test harness ala Test::More, and took advantage of the fact that $initialised was a package global to write a test like
And guess what, I got
It looks like the initialisation never happened - but I know it happened because I sprinkled a lot of print's in _initialise() to see it working. So it looks like the our $initialised = 0; is clobbering the value set in the BEGIN, at run time. I hope I'm not using the terms compile/run time too loosely. After pondering and playing for a while, I came up with this version that seems to be correct.
This works correctly (though I still get the warning about the var only used once), but the declaration of the our $initialised in the BEGIN looks weird. I suppose if you think about the BEGIN as getting run-time behaviour at compile time, it looks less weird, if you squint. So if I can't rely on the our $initialised outside the BEGIN as 'existing' when the BEGIN runs, what are the rules about what is in scope before/during/after a BEGIN ? use brain;
Back to
Seekers of Perl Wisdom
|
|