The problem can be easily described with the following code:
use warnings;
eval "INIT { 1 }";
__END__
Too late to run INIT block at (eval 1) line 1.
mod_perl basically loads all modules as a string eval. And you can't have INIT code blocks in eval. See also the CGI to mod_perl Porting. mod_perl Coding guidelines.
I faced a similar dilemma with Thread::Bless: in the end I made sure initializations would only actually initialize once (even if called multiple times), renamed the INIT code block to sub unitialize and added an INIT block that just does a goto &initialize.
Liz | [reply] [d/l] [select] |
Liz,
My apologies. You are completely correct, INIT and CHECK will not run anywhere in mod_perl. I checked every possible situation I could think of in one of my current mod_perl projects, and nothing worked. So I will now put my foot in my mouth.
Apparently even modules loaded with PerlModule and PerlRequire are at some level eval-ed. Which to me seems ugly, but not being a C programmer or Stas Beckmen, who am I to complain.
After some reading though, it seems to me that the PerlRestartHandler and PerlChildInitHandler could potentially be used to accomplish similar functionality. PerlRestartHandler happens before Apache pre-forks all the children, and PerlChildInitHandler runs at the begining of each child process. Has anyone ever tried to use these as CHECK/INIT replacements?
-stvn
| [reply] [d/l] [select] |
| [reply] |
Liz,
This makes sense that any of the compilation phases BEGIN, CHECK, INIT etc. would not work 100% as expected when eval-ed. They are for affecting the compilation during compile-time, and eval is a run-time construct.
As for the assertion that this will not work with mod_perl, you are partially right. To start, Apache::Registry and similar CGI-to-mod_perl tools do eval the files as strings in order to run them in the persistant mod_perl environment. But this is only one very small (but very commonly used) aspect of mod_perl. The rest of mod_perl is handlers (for each of the Apache request cycles), and while I have not tested this assertion, I am pretty sure that INIT blocks as well as BEGIN, CHECK & END all run perfectly fine.
-stvn
UPDATE:
Wow, was I wrong. Apparently mod_perl evals everything, handlers and all, see my apology to Liz below.
| [reply] |
BEGIN and END work in eval "". It's just CHECK and INIT that have to be set up before the compile of the main script ends or they are "too late".
| [reply] |