如何动态避免使用模块'减少内存占用

时间:2015-09-18 14:55:38

标签: perl memory-management

给出以下模块:

package My::Object;

use strict;
use warnings;

use My::Module::A;
use My::Module::B;
use My::Module::C;
use My::Module::D;

...
1;

我希望能够在接下来的两个场景中调用My :: Object:

  1. 正常使用

    使用My :: Object;

    我::模块 - >新建();

  2. 减少内存使用量。调用相同的对象,但使用条件或标志告诉对象跳过使用模块以减少内存使用。不知何故喜欢:

    使用My :: Object -noUse;

    我::模块 - >新建();

  3. 如果尝试Perl if condition但没有成功。

    我遇到的问题是大型对象有很多用途,然后只加载这个对象会消耗大量的RAM。我知道我可以重构它们,但如果我确定在给定的场景中没有使用它们,我可以避免这些用途,这将是非常好的。

    一个解决方案是在需要模块的时候用所有地方的需求替换所有用途,但是当其中一些用于很多方法时,我看不太方便。

    有什么想法吗?

    由于

2 个答案:

答案 0 :(得分:4)

本机编译指示autouse将加载调用普通子例程时所需的模块:

use autouse 'My::Module::A' => qw(a_sub);
# ... later ...
a_sub "this will dynamically load My::Module::A";

对于正确的OO方法,Class::Autouse将在调用方法时加载模块(类):

use Class::Autouse;
Class::Autouse->autouse( 'My::Module::A' );
# ... later ...
print My::Module::A->a_method('this will dynamically load My::Module::A');

答案 1 :(得分:2)

我认为您正在寻找的可能是require - 需要稍后进行评估,以便您可以在条件中成功使用它:

if ( $somecondition ) {
    require Some::Module;
}

当然,如果你没有加载它,你将无法做Some::Module->new() - 没有办法解决这个问题。

在编译时触发use(因此如果模块不可用,将在perl -c下触发警告)require发生在运行时。您可能应该测试require是否成功。

e.g:

if ( $somecondition ) {
    eval { require Some::Module };
    warn "Module Not loaded: ".$@ if $@;
}

否则你可能正在寻找:

Is it possible to pass parameters to a Perl module loading?

#!/usr/bin/perl

package MyObject;

sub import {
    my ( $package, $msg ) = @_;
    if ( defined $msg and $msg eq "NO_USE" ) {
        #don't load module
    }
    else {
        require XML::Twig;
    }
}

1;

然后致电:

use if $somecondition, MyObject => ( 'NO_USE'  );

或者更简单:

use MyObject qw( NO_USE );

编辑:

经过一些摆弄“使用” - 有一些问题,因为use if似乎不喜欢词汇变量。所以你需要做一些事情:

#!/usr/bin/perl

package MyObject;
use strict;
use warnings;

our $import_stuff = 1;

sub import {
    my ( $package, $msg ) = @_;
    if ( $msg and $msg eq "NO_USE" ) {
        $import_stuff = 0;
    }
    use if $import_stuff, 'Text::CSV';
}

1;

并致电:

#!/usr/bin/perl
use strict;
use warnings;

use MyObject qw( NO_USE );
use Data::Dumper;

print Dumper \%INC;
my $test = Text::CSV -> new();

(如果设置NO_USE则会出现哪些错误,否则无效)。

认为这是use仍然是编译时指令的工件,因此需要一个(包范围)条件。