2011-11-10 4 views
2

さまざまなデリゲートをすべて含めるのではなく、どのデリゲートを使用するかに基づいてパッケージを動的に含める方法はありますか?デリゲートとして使用するパッケージをどのように「遅延ロード」しますか?

私はこの代理人の使い方についてこの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; 

に持ってこれが機能するためには、おそらく(遅延ロードのいくつかの種類のような)すべてのパッケージを使用することなく、デリゲートを行うには良い方法はありますか?あなたの例では

答えて

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を使用するとよいでしょう。

関連する問題