Use of eval to load modules

杀马特。学长 韩版系。学妹 提交于 2019-12-11 03:40:55

问题


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


回答1:


Use Module::Load instead.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/6855970/use-of-eval-to-load-modules

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!