2010-01-08 32 views
4

我有一個數字,我從下載數據和按摩到其他格式(使用Perl)在工作中使用不同的站點,都辦起一個Perl腳本還挺像這樣的:如何查找從Perl中的包繼承的所有包?

#! /usr/bin/perl 
use strict; 

use My::Package1; 
use My::Package2; 

my $p1 = My::Package1->new; 
$p1->download; 

my $p2 = My::Package2->new; 
$p2->download; 

等等等。目前,每個My::Package是它自己的包;它不會從基本包或任何東西繼承。我打算使用Moose重新編寫它們,我希望在每次添加新軟件包時都不必編輯運行下載的Perl腳本,而是可能有一種方法可以找到從基本軟件包繼承的軟件包,然後在一個循環實例每做下載,有點像這樣:

#! /usr/bin/perl 
use strict; 

for my $pname (packages_that_inherit_from("My::Package")) { 
    my $package = $pname->new; 
    $package->download; 
} 

是嗎,什麼ILKE它,可能嗎?

TIA

+1

爲什麼不提供一個配置文件來使用軟件包的名稱? – 2010-01-08 03:26:11

+0

我想避免不得不將新包添加到另一個文件,無論是perl腳本還是配置文件。 – Mark 2010-01-08 03:50:41

回答

2

你所要求的不會是可能的,因爲沒有你正在尋找使用的軟件包將尚未加載。爲什麼不把所有的軟件包放在一個公共目錄中,然後讓你的腳本打開該目錄,併爲每個文件都要求它,然後實例化你的對象。

1

基於繼承,沒有辦法做到這一點,因爲父類甚至不知道它是否具有後代,不必介意它有多少或它們的名字是什麼。

use Module::Pluggable require => 1, search_path => ['Parent']; 
my @descendants = plugins(); 

但是,如果按照使用分層命名空間和命名的後裔爲Parent::FooParent::Bar等的共同約定,您可以通過使用Module::Pluggable加載了Parent命名空間下的一切接近這個

因爲這是基於命名空間的,所以它會拉動Parent::Helper::ThatIsNotAChild,而錯過Child::NotUnder::Parent::Namespace,所以它不完全完美。

6

使用MooseClass::MOP基礎,您可以找到分配給每個類(在該時間點)的子類。

Class::MOP::Class文檔:

$ metaclass->子類 這將返回所有子類這個類,甚至間接子類的列表。

$ metaclass-> direct_subclasses 這將返回此類的直接子類的列表,該子類不包括間接子類。

因此,舉例來說,如果我們建立這些類:

{ 
    package Root; 
    use Moose; 
    use namespace::clean -except => 'meta'; 

    sub baz  { say 'Some root thingy' } 
    sub download { say "downloading from " . __PACKAGE__ } 
} 

{ 
    package NodeA; 
    use Moose; 
    extends 'Root'; 
    use namespace::clean -except => 'meta'; 
    sub download { say "downloading from " . __PACKAGE__ } 
} 

{ 
    package NodeA1; 
    use Moose; 
    extends 'NodeA'; 
    use namespace::clean -except => 'meta'; 
    sub download { say "downloading from " . __PACKAGE__ } 
} 

然後使用你的例子,我們可以做到這一點的基礎:

for my $pname (Root->new->meta->direct_subclasses) { 
    my $package = $pname->new; 
    $package->download; 
} 

# => "downloading from NodeA" 

所以上面運行NodeA->download。更改爲meta->subclasses也將運行NodeA1->download

/I3az/

3

雖然你說你正在向Moose,非Moose的辦法是把所有的衍生產品基於該基礎包名已知的子目錄。然後加載所有模塊

例如,如果您的基本軟件包是Local::Downloader,則所有派生軟件包均以Local::Downloader::Plugin或類似內容開頭。然後,您在@INC中查找所有模塊.../Local/Downloader/Plugin/...。儘管自己做起來並不難,但像Module::PluginFinder這樣的東西也可以爲你做到。

相關問題