wazzuteke has asked for the wisdom of the Perl Monks concerning the following question:

I've recently been working in a Mason web app and am having issues of the Mason compiler seemingly skipping a used modules' INIT. Now I must say my intelligence of Mason's uses are moderate at best, so I may very well be missing something. Plus, I'm working in a quite legacy application that is far from perfect. That said, here is an example.

Example of included module
package Foo; use strict; use warnings; INIT { { no strict 'refs'; *Foo::bar = sub{ return 1; }; } } sub new { return bless {}, shift; }


Example of Mason Page
<%init> use Foo; </%init> % print Foo->bar();


Simple enough. But, in this example, I'm seeing that bar is not defined in Foo. After further (and intense, multiple times on different yet similar issues) investigation, I can find no proof that the code within the INIT block is even getting executed. Even more interesting is that knowing Perl as I do, I can't find any reasonable or logical explanation into why or /how/ this could even be happening (unless, maybe, Mason takes it upon it's self to parse included modules and ignore specific code blocks before adding adding them to the %INC path... but I would hate to believe it does that.)

That's it. Any help appreciated and thanks in advance for your bits of wisdom.

---------
perl -le '$.=[qw(104 97 124 124 116 97)];*p=sub{[@{$_[0]},(45)x 2]};*d=sub{[(45)x 2,@{$_[0]}]};print map{chr}@{p(d($.))}'

Replies are listed 'Best First'.
Re: Mason's interpretation of INIT blocks
by ysth (Canon) on Feb 27, 2009 at 08:00 UTC
    Do you get a "Too late to run INIT block" warning?

    If Mason is only compiling your code after the main perl run phase has started, you'd expect the INIT block to not be run, with a warning.

    If you can, avoid using INIT in modules, ever. Since it is tied to beginning the main run phase, it is only well suited for use in your main program (which doesn't exist in Mason?) If you can't, you may need something like Manip::END, only for INIT blocks. They are also accessible via B::init_av and object_2svref.

Re: Mason's interpretation of INIT blocks
by tilly (Archbishop) on Feb 27, 2009 at 12:48 UTC
    Just to follow up on ysth's comment, what you need to do is make sure that the INIT blocks are removed, or else make sure that your module is preloaded when mod_perl starts.

    Of the two, I strongly recommend removing INIT blocks. And the fact that Attribute::Handlers has a dependency on CHECK and INIT is a major reason that I personally avoid attributes.