perl:"不包括"模块

pep*_*eph 4 perl perl-module

所以,我有一个这样的程序:

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

每个包含的模块有点类似,唯一的区别是process() - sub的作用.

#!/usr/bin/perl -w  
use strict;  
sub process {  
...  
}
Run Code Online (Sandbox Code Playgroud)

我的问题:主脚本的输入是一个(可能很长)的事情列表,而处理该列表我得到连续的"子程序重新定义"错误(显然).有没有办法"取消使用"模块?
由于包含的可能"行动"库可能会在未来增长,我认为这种动态包含模块的方式将是最好的方法.非常感谢您的帮助 :)

Tud*_*tin 7

正如@pilcrow所说,你可以通过使用require而不是快速解决这个问题use,但是,我认为这是使用多态性的一个很好的例子.

您可以创建一个基类,如:

package Processors::Base;

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

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

1;
Run Code Online (Sandbox Code Playgroud)

然后,将您的处理器创建为从此基础包继承的包.

package Processors::Foo;

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

1;
Run Code Online (Sandbox Code Playgroud)

然后你的代码看起来像:

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

当然,修改假设例如$_是以形式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;
Run Code Online (Sandbox Code Playgroud)

然后,您的代码将如下所示:

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

foreach (@data) { 
    Processors::Factory->get_instance( $_ )->process();
    ...  
}
Run Code Online (Sandbox Code Playgroud)