2010-01-08 2 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; 
} 

Является ли это, или что-то Илке это, возможно?

ТИА

+1

Почему бы не указать конфигурационный файл с именами используемых пакетов? –

+0

Мне не хотелось добавлять новые пакеты в другой файл, будь то perl-скрипт или файл конфигурации. – Mark

ответ

2

Что вы просите обыкновение быть возможным, потому что ни один из пакетов, которые вы собираетесь использовать не будут загружены еще. Почему бы не поместить все пакеты в общий каталог, а затем открыть сценарий для этого файла, а для каждого файла - его, а затем создать экземпляр объектов.

1

Невозможно сделать это на основе наследования, потому что родительский класс даже не знает, есть ли у него потомки, неважно, сколько у него есть или как их имена.

Однако, если вы будете следовать общей конвенции использования иерархических пространств имен и имен потомков, как Parent::Foo, Parent::Bar и т.д., вы можете приблизить это с помощью Module::Pluggable, чтобы загрузить все под Parent имен:

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

Так как это основано на пространствах имен, оно будет тянуть в Parent::Helper::ThatIsNotAChild, а отсутствует Child::NotUnder::Parent::Namespace, так что это не совсем идеально.

6

Использование Подчинение вы можете найти подклассы, присвоенные каждому классу (в этот момент времени).

От 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 может сделать это и для вас.

 Смежные вопросы

  • Нет связанных вопросов^_^