在运行时在Perl中自动加载perl模块

时间:2012-02-27 18:14:41

标签: perl memory-management

有没有办法在运行时在Perl中加载整个模块?我以为我找到了autouse的一个很好的解决方案但是下面的代码无法编译:

  
    

包tryAutouse2;
    使用autouse'tryAutouse';
    我的$ obj = tryAutouse-> new();

  

我想这是因为autouse专门用于导出函数,我是否正确?由于编译失败,是不可能有一个打包的解决方案?如果我想要动态加载,我会在每次新模块调用之前强制require吗?

这背后的原因是我的团队加载了很多模块,但我们担心这会占用内存。

5 个答案:

答案 0 :(得分:5)

您需要Class::AutouseClassLoader

由于魔法太多,为方便起见,我只在我的REPL中使用ClassLoader。对于严肃的代码,我总是明确地加载类。 Jack Maney在评论中指出Module::LoadModule::Load::Conditional适合延迟加载。

答案 1 :(得分:4)

要求IMO没有任何问题。跳过函数的导出,只需调用完全限定名称:

require Some::Module;
Some::Module::some_function(@some_arguments);

答案 2 :(得分:1)

eval 'use tryAutouse; 1;' or die $@;

会工作吗?但你可能想隐藏丑陋。

答案 3 :(得分:1)

当你说:

use Foo::Bar;

您正在编译时加载模块Foo::Bar。因此,如果要在运行时加载模块,则使用require

require Foo::Bar;

它们等同于,但存在差异。请参阅use上的Perldoc以了解完全不同之处。例如,以这种方式使用的require将不会自动加载导入的函数。这对你来说很重要。

如果您想测试模块是否存在,请在require中包含eval语句,并测试eval是否成功。

我使用类似的技术来查看特定的Perl模块是否可用:

eval { require Mail::Sendmail; };
if ($@) {
    $watch->_Send_Email_Net_SMTP($watcher);
    return;
}

在上面,我将尝试使用Mail::Sendmail,如果它可用,它是一个可选模块。如果没有,我将运行另一个使用Net::SMTP的例程:

sub _Send_Email_Net_SMTP {
    my $self    = shift;
    my $watcher = shift;

    require Net::SMTP;  #Standard module: It should be available

WORD O'WARNING :您需要在eval语句周围使用花括号而不是括号。否则,如果require不起作用,您的程序将退出,这可能不是您想要做的。

答案 4 :(得分:1)

指令'use'在编译时执行,因此检查模块的路径也在编译时进行。这可能会导致错误的行为,在您考虑@INC数组的内容之前很难理解。

一种解决方案是添加块'BEGIN',但下面显示的解决方案不够优雅。

BEGIN { unshift @INC, '/path/to/module/'; }
use My::Module;

你可以用一个简单的指令替换整个混乱:

use lib '/path/to/module';
use My::Module;

这是有效的,因为它是在编译时执行的。所以一切都准备好执行'使用'指令。

您可以决定在编译时执行不同的指令,而不是'BEGIN'块,即声明一个常量。

use constant LIB_DIR => '/path/to/module';
use lib LIB_DIR;
use My::Module;