4

だから、私はこのようなプログラムを持っています:

#!/usr/bin/perl -w  
use strict;  
foreach (@data) {  
    if($_ eq "foo") {  
        use Foo;
        process();
    }  
    if($_ eq "bar") {  
        use Bar;
        process();
    }  
...  
}

含まれている各モジュールは多少似ていますが、唯一の違いはprocess()-subの機能です。

#!/usr/bin/perl -w  
use strict;  
sub process {  
...  
}

私の問題:メインスクリプトの入力は(おそらく長い)もののリストですが、そのリストを処理している間、(明らかに)継続的な「サブルーチンの再定義」エラーが発生します。モジュールを「使用しない」方法はありますか?
含めることができる「アクション」のライブラリが将来増える可能性があるという事実のために、モジュールを動的に含めるこの方法が最善のアプローチであると思いました。助けてくれて本当にありがとうございます :)

4

1 に答える 1

7

require@pilcrowが言ったように、代わりにを使用することでこの問題をすばやく解決できますが、これはポリモーフィズムuseが使用される良い例だと思います。

次のような基本クラスを作成できます。

package Processors::Base;

sub new{
  my $class = shift;
  return bless {}, $class;
}

sub process{
  die "You can only use a subclass of me";
}

1;

次に、この基本パッケージから継承するパッケージとしてプロセッサを作成します。

package Processors::Foo;

sub process{
  ... do stuff ...
}

1;

次に、コードは次のようになります。

#!/usr/bin/perl -w  
use strict;  
for my $pkg (@data) { 
    (my $path = $pkg) =~ s{::}{/}g;
    require "$path.pm";
    $pkg->process; 
    ...  
}

もちろん、変更は、たとえば$_の形式であることを前提としています。Processors::Fooの内容を変更できなくても、プロセッサの名前を生成して、そのメソッド@dataを呼び出すことができると思います。process()

見せびらかしたい場合はFactory、の値に基づいてプロセッサのインスタンスを返すオブジェクトを作成でき$_ます。

package Processors::Factory;

sub get_instance{
  my ($self, $processor_name) = @_;

  my $full_processor_name = sprintf('Processors::%s', ucfirst($processor_name) );

  (my $full_processor_path = $full_processor_pkg) =~ s{::}{/}g;
  require "$full_processor_path.pm";

  my $processor = $full_processor_name->new();

  return $processor;
}

1;

次に、コードは次のようになります。

#!/usr/bin/perl -w  
use strict;
use Processors::Factory;

foreach (@data) { 
    Processors::Factory->get_instance( $_ )->process();
    ...  
}
于 2012-10-25T15:05:43.840 に答える