【问题标题】:perl: "unincluding" modulesperl:“不包括”模块
【发布时间】:2018-09-20 08:13:40
【问题描述】:

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

#!/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 {  
...  
}

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

【问题讨论】:

  • 在您的情况下,不需要use,而是使用require
  • @pilcrow +1 出色的措辞,好先生。
  • Foo::process(...)Bar::process(...) 是否会增加这么多的输入。虽然我很喜欢 Tudor 的多态示例,但它并不一定比use Foo (); Foo::process() 更难。如果模块使用Exporter 管理其导出,则空列表让它知道我们不需要导出。
  • 永远不要在没有 package 的情况下使用 userequire。为此使用do
  • @pilcrow,它仍然会给出重新定义的警告,如果输入是qw( foo bar foo),它仍然会失败。

标签: perl perl-module


【解决方案1】:

正如@pilcrow 所说,您可以通过使用require 而不是use 来快速解决此问题,但是,我认为这是使用Polymorphism 的一个很好的例子。

你可以像这样创建一个基类:

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();
    ...  
}

【讨论】:

  • require "Foo::Bar"; 查找名为 Foo::Bar 的文件。固定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-25
  • 2013-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多