2012-10-25 34 views
4

所以,我有一個程序是這樣的:perl的:「unincluding」模塊

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

每個包括模塊有些類似,唯一的區別是處理()什麼 - 子一樣。

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

我的問題:主要用於腳本輸入的東西(可能很長)列表,在處理該列表中我得到連續的「子程序重新定義了」錯誤(顯然)。有沒有辦法「解除」使用模塊?
由於事實的可能「行動」的圖書館,包括在未來可能會增長,我想包括模塊動態將是最好的方法的這種方式。您的幫助:)

+5

在你的情況下,並不需要'use',而是使用'require'。 – pilcrow

+2

@pilcrow +1爲精彩的措辭,好先生。 –

+0

是否添加太多的打字編寫'美孚::過程(...)'和'欄::過程(...)'。雖然我很喜歡都鐸王朝的多態示例,但它不一定比'使用Foo()'更難。富::過程()'。如果該模塊使用「出口商」來管理其出口,則空列表讓它知道我們不需要出口。 – Axeman

回答

7

正如@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(); 
    ... 
} 
+1

'需要「富::酒吧」;'查找一個名爲'富:: Bar'文件。固定。 – ikegami

+0

謝謝你的那位先生:) –