所以,我有一个这样的程序:
#!/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 {
...
}
我的问题:主脚本的输入是一个(可能很长)的事情列表,而处理该列表我得到连续的“子程序重新定义”错误(显然)。有没有办法“取消使用”模块?
由于包含的可能“行动”库可能会在未来增长,我认为这种动态包含模块的方式将是最好的方法。非常感谢你的帮助:))
答案 0 :(得分:7)
正如@pilcrow所说,您可以使用require
代替use
来快速解决此问题,但是,我认为这是一个使用Polymorphism的好例子。< / p>
您可以创建一个基类,如:
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();
...
}