I have a Perl program, that needs to use packages (that I also write). Some of those packages are only chosen in Runtime (based on some environment variable). I don\'t want
Many years later, eval "use $mod_name";
seems to work just fine (as of at least 5.8.8).
The advantage over eval "require $mod_name";
is that the loaded module's default exports are automatically imported; in other words:
eval "use $mod_name";
is the shorter equivalent of
eval "require $mod_name"; $mod_name->import();
Here's a test command, which passes the name of the module via env. variable mod_name
, loads and imports the module, then uses an imported function (assumes a POSIX-like shell):
$ mod_name='Data::Dumper' perl -e 'eval "use $ENV{mod_name}"; print Dumper("hi!")'
$VAR1 = 'hi!';
I may be missing subtleties; if so, please let me know.
You probably want to use require
instead of use
if you don't want it to happen at compile time, and then manually import any symbols you might need. See this link to the Perl Cookbook (from Google Books) for a good discussion of methods you can use to achieve what you want.
I think that a module loaded in runtime can be a Plugin. I have this kind of problem, having specific modules to some cases that are loaded in run time as plugins with Module::Pluggable.
Maybe you need to change the logic of your modules, but it works and scale very well (my app started with four modules and now have twenty and it's growing).
How about using the core module Module::Load
With your example:
use Module::Load;
load $ENV{a};
"Module::Load - runtime require of both modules and files"
"load eliminates the need to know whether you are trying to require either a file or a module."
If it fails it will die with something of the like "Can't locate xxx in @INC (@INC contains: ...".
I would use UNIVERSAL::require. It has both require and use methods to use a package. The use method will also call import for the package.
use UNIVERSAL::require;
$ENV{a}->use or die 'Could not import package: ' . $@;
"use" Statements are run at compilation time, not at run time. You will need to require your modules instead:
my $module = "Foo::Bar";
eval "require $module";