Reputation: 31
I'm facing some trouble with Perl and built-in function eval
.
I have looked around the web but I can't find any answer or sample code.
I'd like to load modules dynamically (I don't know them before the execution time)
$module_name="Auth_Auth_Test";
my $ret1;
ret = eval{
"use ".$module_name;
$ret1 = $module_name."::test(".$log.")";
};
$log->debug ($@) if $@;
$log->debug ("Ret".$ret1);
The return was :
RetAuth_Auth_Test::test(Custom::Log=HASH(0x1194468))
The following method worked for me but I can't load more than one module with same subroutine :
my $use = "use ".$module_name." qw(&test)";
$ret = eval $use;
# Debug for eval
$log->debug ($@) if $@;
$ret = test($log);
Thank you for any help
Upvotes: 3
Views: 2074
Reputation: 5210
I strongly advise you to use Class::Load, it is ubiquitous nowadays due to being Moose dependency:
use Class::Load qw(:all);
my $module = 'Web::Spider::' . $module;
try_load_class($module)
or warn "unable to load '$module'";
And here is an extensive explication on why it is better than Module::Load (despite the late being part of Perl core): http://blog.fox.geek.nz/2010/11/searching-design-spec-for-ultimate.html
TL;DR:
A quirk of how Perl 5.8 functions ( which is now solved in 5.10 ) is that once a module is require'd, as long as that file existed on disk, $INC{ } will be updated to map the module name to the found file name. This doesn't seem to bad, until you see how it behaves with regard to that being called again somewhere else.
Class::Load solves that. Module::Load doesn't.
Upvotes: 3
Reputation: 9697
In first snippet, the
"use ".$module_name;
is just evaluated as string. It is because difference between string eval
and block eval
. See eval documentation for differences between those.
You can use something like this:
use strict; use warnings;
my $module_name = "Auth_Auth_Test";
eval "require $module_name";
if($@) {
warn "Could not load module: $@\n";
}
my $ret = $module_name->test("params");
print "return $ret\n";
But anyway, daxim's suggestion is sound, you don't probably want to reinvent something already distributed with perl. Module::Load is in core since 5.9.4.
Upvotes: 2