How do I load a module at runtime in Perl?
Is it possible to load a module at runtime in Perl? I tried the following, but it didn't work. I wrote the following somewhere in the program:
require some_module;
import some_module开发者_如何转开发 ("some_func");
some_func;
Foo.pm
package Foo;
use strict;
use warnings;
use Exporter qw(import);
our @EXPORT = qw(bar);
sub bar { print "bar(@_)\n" }
1;
script.pl
use strict;
use warnings;
require Foo;
Foo->import('bar');
bar(1, 22, 333);
The easiest way is probably to use a module like Module::Load:
use Module::Load;
load Data::Dumper;
Look at this "How to dynamically load modules" and you can also look at [DynaLoader - Automatic Dynamic Loading of Perl Modules] in Programming Perl.
Given the name of a package, use it as a bareword with use
or require
:
use Some::Module;
require Some::Module;
To import symbols, you can give additional arguments to use
(and with no arguments, it imports all default symbols as defined by the package):
use Some::Module qw(func1 func2 ...)
With require
you have to call import yourself:
require Some::Module;
Some::Module->import( qw(func1 func2 ...) );
You'll see in the use docs that it's a fancy form of require
that happens at compile time:
BEGIN { require Module; Module->import( LIST ); }
Now, that's how most modules are loaded most of the time. There's another answer that comes up when people don't know the name of the package ahead of time.
Given some package name is a string, there are various things that you can do. Various modules mentioned in other answers merely do this for you.
The require can do this in an eval
:
eval "require $class" or die ...;
People are nervous about eval
because it's easy for anything to show up in $class
and they might run unintended code. But, that's what the convenience modules often end up doing for you, wrapped in some sanity checks.
A step beyond that, you can convert the class name to a file name. Perl 5 is easy like that because the ::
become the directory separator and you add a .pm
on the end. You can then give that filename to require
and it will look for it in @INC
:
# sanity check, moderately restrictive
die "Bad name!" unless m/\A [A-Za-z0-9_]+ (::[A-Za-z0-9_])* \z/x;
my $filename = "$class.pm";
$filename =~ s/::/\//g;
require $filename;
You may not want to do this work yourself because it's easy to mess up, and using another module is probably not a problem. However, sometimes the weight of adding another third-party dependency isn't worth it. That's a different question and its answer depends on local context.
精彩评论