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

I need to load perl modules on the fly from mod_perl. Here is my working solution.

In an apache conf file I have:

<FilesMatch "\.pm"> PerlSetVar RootNamespace CEMS::EXT PerlFixupHandler CEMS::AutoLoader </FilesMatch>
The code above tells apache to execute CEMS::AutoLoader::handler() whenever it sees a uri that looks like *.pm

Module CEMS::AutoLoader looks like this

package CEMS::AutoLoader; use Apache::Constants qw(:common); use strict; sub handler { my $r = shift; return DECLINED unless $r->is_main; #get package name my $module = join ('::',$r->dir_config('RootNamespace'), split (/\//, substr($r->uri(),1,-3) ) ); #see if package really exists and set content handler if (eval "require ".$module) { $r->push_handlers(PerlHandler => $module); $r->handler('perl-script'); return OK; } #require threw an exception so package does not exist return DECLINED if ($@); } 1;

The above code is working, but there has to be a better way to do this. Calling require on every request just to see if a package exists probably isn't efficient. Most likely the package will already be loaded.

Does someone know of a better way to see if a package is already loaded?

Edit kudra, 2001-08-30 Added p breaks; code->single spaced

Replies are listed 'Best First'.
Re: loading modules on the fly with mod_perl
by perrin (Chancellor) on Aug 30, 2001 at 16:47 UTC
    You should use Apache::Dispatch for this. It has been debugged by the community and the security issues (of which there are plenty with this kind of thing) have been dealt with.

    However, your code is not so inefficient. Your call to require will check to see if the module is in %INC (i.e. if it has been loaded before) and will not load it again if it is.

      I concur, there's no API in mod_perl to require modules. In fact Apache::Dispatch does the same as the poster (Dispatch.pm line 154) :
      eval "require $class";
Re: loading modules on the fly with mod_perl
by blakem (Monsignor) on Aug 31, 2001 at 04:41 UTC
Re: loading modules on the fly with mod_perl
by princepawn (Parson) on Aug 30, 2001 at 17:09 UTC
    this part of yyour code confuses me:
    #get package name my $module = join ('::',$r->dir_config('RootNamespace'), split (/\//, substr($r->uri(),1,-3) ) );
    $r->dir_config returns CEMS::EXT so I dont see why you would want to join a string with ::. also the split of the URI doesn't look like your are leveraging the API properly. Perhaps
    $r->filename
    is in order.

    and finally, you can get rapid help with this from the modperl mailing list