你如何“懒惰加载”包用作代表?

时间:2011-11-10 05:32:29

标签: perl oop delegates moose

有没有办法可以根据使用的代理动态包含一个包,而不是必须包含所有不同的代理?

我发现这个example关于如何使用委托,但它掩盖了我试图理解的细节。这是写的方式,它基本上都是一个文件...

package Compare;
use Moose::Role;
requires 'compare';


package SpaceshipCompare;
use Moose;
with 'Compare';  

sub compare { my ($a, $b) = @_; return $a <=> $b }

package Sort;
use Moose;

has 'comparer' => (
    is       => 'ro',
    does     => 'Compare',
    handles  => 'Compare',
    required => 1,
);

sub my_sort {
    my ($self, @list) = @_;
    return sort { $self->compare($a, $b) } @list;
}

用法:

my $sorter = Sort->new( comparer => SpaceshipCompare->new );
my @sorted = $sorter->my_sort("1one", "0", "43");

在我的委托实现中,我正在使用基于传递给构造函数的参数的不同资源。

  sub BUILD{
    my($this,$args) = @_;

        if($args->{cachedDataSource} eq 'local'){

            $this->setDataStore( Cache::LocalCache->new() ); 

        }

        if($args->{cachedDataSource} eq 'remote'){

            $this->setDataStore( Cache::RemoteCache->new() ); 

        }


        if($args->{cachedDataSource} eq 'memd'){

            $this->setDataStore( Cache::MemedCache->new() ); 

        }

}

但为了实现这一点,我必须

use Cache::LocalCache;
use Cache::RemoteCache;
use Cache::MemedCache;

有没有更好的方法来代理,而不必使用所有的包(比如某种延迟加载)?

1 个答案:

答案 0 :(得分:5)

在您的示例中,您只需使用require

sub BUILD{
    my($this,$args) = @_;

        if($args->{cachedDataSource} eq 'local'){
            require Cache::LocalCache;
            $this->setDataStore( Cache::LocalCache->new() ); 
        }

        if($args->{cachedDataSource} eq 'remote'){
            require Cache::RemoteCache;
            $this->setDataStore( Cache::RemoteCache->new() ); 
        }

        if($args->{cachedDataSource} eq 'memd'){
            require Cache::MemedCache;
            $this->setDataStore( Cache::MemedCache->new() ); 
        }
}

由于require是一个运行时操作,因此在实际需要之前不会加载该类。如果您的用户传递了类名,那么它会变得更复杂一些。您可能希望使用Module::Load