[jifty-devel] Classloader's loader

Gaal Yahas gaal at forum2.org
Sun Oct 22 05:36:29 EDT 2006


On Thu, Oct 19, 2006 at 12:10:20AM -0400, Jesse Vincent wrote:
> On Wed, Oct 18, 2006 at 11:39:25AM +0200, Gaal Yahas wrote:
> > Bitten again by a silently failing module, I found that the "require"
> > called by the classloader is not the one provided by UNIVERSAL::require,
> > but rather that of Module::Pluggable. So UNIVERSAL::require::ERROR is
> > not set, and compilation failures are ignored.
> 
> Ooh. thanks for tracking that down!
> 
> > This is probably not as intended. I'm not just committing a simple fix ($@
> > should still be valid) because it looks like the classloader is interested
> > in the module's return value -- which implies getting UNIVERSAL::require
> > back. Could someone advise what the proper course is here?
> 
> I believe the return value checking was entirely to work around people
> not getting their Dispatcher rules right.  We definitely want to be
> using UNIVERSAL::require's require and not M::P. (Just to be clear,
> we're talking about Jifty::Util->require(), right?

(Yes, Jifty::Util->require().)

Okay, this is tricker than I thought.

First off, we can't just get back UNIVERSAL::require by controling its
load order relative to Module::Pluggable. M::P's _require is always used,
and it calls CORE::require, bypassing U::require. Second, its design is
the questionable:

    sub _require {
        my $self = shift;
        my $pack = shift;
        eval "CORE::require $pack";
        return $@;
    }

That is, it reverses the meaning of require's truth value (and loses
distinction among successful return values, but that's not important
here.) As John points out we can't get rid of M::P entirely.

The Perly fix, I suppose, is to override it:

Jifty::Everything (or probably in a new module required by it):

    # after 'use Module::Pluggable'

    # only needs to be done once, so can remove from
    # Jifty::ClassLoader/Util
    use UNIVERSAL::require;

    {
        no strict 'refs';
        no warnings 'redefine';
        *{'Module::Pluggable::Object::_require'} = sub {
             my($self, $pack) = @_;
             UNIVERSAL->require($pack);
             return $@;
        };
    }

I don't like this very much because it feels Jengaish, so please comment
if you have a better idea. It does work, anyhow.

-- 
Gaal Yahas <gaal at forum2.org>
http://gaal.livejournal.com/


More information about the jifty-devel mailing list