For the project I work on many of our Modules derive from a common
Root module which contains the following dynamic_use call which is
exactly the same as a use line - but does not fail fatally if the
module isn't there - it also nicely means that the code isn't
loaded up front (as if all blocks of code were included with a
normal use line)... it seems to work OK for the project (which
has a nice plugin system)

our $failed_modules;

sub dynamic_use {
  my( $self, $classname ) = @_;
  unless( $classname ) {
    my @caller = caller(0);
    my $error_message = "Dynamic use called from $caller[1] (line
$caller[2]) with no classname parameter\n";
    warn $error_message;
    $failed_modules->{$classname} = $error_message;
    return 0;
  }
  if( exists( $failed_modules->{$classname} ) ) {
  #  warn "EnsEMBL::Web::Root: tried to use $classname again - this has
already failed $failed_modules->{$classname}";
    return 0;
  }
  my( $parent_namespace, $module ) = $classname =~/^(.*::)(.*)$/ ? ($1,$2)
: ('::',$classname);
  no strict 'refs';
  return 1 if $parent_namespace->{$module.'::'} && %{
$parent_namespace->{$module.'::'}||{} }; # return if already used
  eval "require $classname";
  if($@) {
    warn "EnsEMBL::Web::Root: failed to use
$classname\nEnsEMBL::Web::Root: $@" unless $@ =~/^Can't locate /;
    $parent_namespace->{$module.'::'} = {};
    $failed_modules->{$classname} = $@ || "Unknown failure when
dynamically using module";
    return 0;
  }
  $classname->import();
  return 1;
}

sub dynamic_use_failure {
  my( $self, $classname ) = @_;
  return $failed_modules->{$classname};
}



On Mon, 21 Aug 2006, John ORourke wrote:

> Arshavir Grigorian wrote:
>
> > I am wondering if anyone has experience with a framework for
> > dynamically loading certain modules into an application and executing
> > certain code based on whether a certain module is loaded (available or
> > not). By "dynamically", I do not mean loading run-time, only being
> > able to safely exclude certain modules at startup. One place this
> > could come in handy is when selling an app to 2 clients of whom one
> > has purchased all the functionality and the other has not, and you
> > don't want to give them certain module(s). I am guessing one could
> > accomplish this by using a macro processor (m4) to preprocess Perl
> > code before it's "released", but it would probably be somewhat
> > painful.
>
>
> I'm just finishing a plugin architecture which dynamically loads
> available plugins, but in doing so I found some useful CPAN modules:
>
> Module::Optional - exactly what you're after
> Module::Pluggable - very flexible plugin/optional module manager
>
> hth,
> John
>
>

Reply via email to