in reply to RFC : Pragma vs. Module

Class::Trait does 90% of its work in the BEGIN phase, the other 10% in the INIT phase...

Please note that if you depend on the INIT {} code block for your functionality, then you cannot use your module with mod_perl. You should at least provide an alternative way to perform functionality currently done in the INIT phase.

Yes, INIT {} functionality is virtually useless if you want to create a generic module and/or a module that should work under mod_perl.

Liz

Update:
Slight rewording of 1st paragraph.

Replies are listed 'Best First'.
Re: Re: RFC : Pragma vs. Module
by stvn (Monsignor) on Mar 14, 2004 at 21:38 UTC

    Could you please elaborate on why you can't/shouldn't use INIT with mod_perl? I have never heard of that restriction before, although to be honest, I have never looked either (or ever had a reason too look).

    -stvn
      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

        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
        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.