Как я могу вызвать класс Perl с более коротким именем? - PullRequest
9 голосов
/ 16 сентября 2009

Я пишу модуль Perl Galaxy::SGE::MakeJobSH с OO.

Я хочу использовать MakeJobSH->new() вместо Galaxy::SGE::MakeJobSH->new(), или некоторые другие короткие имена. Как я могу это сделать?

Ответы [ 5 ]

12 голосов
/ 16 сентября 2009

Вы можете предложить своим пользователям использовать модуль aliased для загрузки вашего:

use aliased 'Galaxy::SGE::MakeJobSH';
my $job = MakeJobSH->new();

Или вы можете экспортировать имя вашего класса в переменную с именем $MakeJobSH;

use Galaxy::SGE::MakeJobSH;  # Assume this exports $MakeJobSH = 'Galaxy::SGE::MakeJobSH';
my $job = $MakeJobSH->new();

Или вы можете экспортировать функцию MakeJobSH, которая возвращает имя вашего класса:

use Galaxy::SGE::MakeJobSH;  # Assume this exports the MakeJobSH function
my $job = MakeJobSH->new();

Хотя я не уверен, что это отличная идея. Людям обычно не нужно часто вводить имя класса.

Вот что вы будете делать в своем классе для последних двух вариантов:

package Galaxy::SGE::MakeJobSH;

use Exporter 'import';
our @EXPORT = qw(MakeJobSH $MakeJobSH);

our $MakeJobSH = __PACKAGE__;
sub MakeJobSH () { __PACKAGE__ };

Конечно, вы, вероятно, захотите выбрать только один из этих методов. Я просто объединил их, чтобы избежать дублирования примеров.

3 голосов
/ 16 сентября 2009

Я не беспокоюсь о псевдонимах. Я думаю, что это неправильный путь. Если вы просто хотите меньше печатать, это может быть ответом (но является ли новая зависимость большей выгодой, чем риском?). Мне не нравится идея обмануть программиста по обслуживанию, скрывая от него настоящее имя, поскольку создание псевдонимов происходит далеко от его использования, и нет никаких признаков того, что то, что выглядит как имя класса, не является реальным классом.

В основном я ищу простое создание подклассов, поэтому я позволю классу решить для себя, какой модуль будет реализовывать деталь.

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

 package Foo::Bar;

 sub foo_class { 'Foo' }

 sub new {
      ....
      eval "require $self->foo_class";
      $self->foo_class->do_something;
      }

В приложении я выбираю 'Foo :: Bar':

 #!perl
 use Foo::Bar;

 my $obj = Foo::Bar->new();

Позже мне нужно специализировать Foo, поэтому я создаю подкласс, переопределяя нужные мне части:

 package Foo::Bar::Baz;
 use parent 'Foo::Bar';

 sub foo_class { 'Local::Foo::SomeFeature' }

 1;

Другое приложение использует почти все те же вещи, но с небольшим изменением:

 #!perl
 use Foo::Bar::Baz;

 my $obj = Foo::Bar::Baz->new();

Вы также можете сделать то же самое на уровне приложения, если вы хотите написать одну программу и позволить пользователям выбирать класс через конфигурацию.

2 голосов
/ 16 сентября 2009

Спасибо cjm.

Я просто выбрал встроенный псевдоним.

require Exporter;

our @ISA = qw(Exporter);
our @EXPORT = qw(MakeJobSH);

sub MakeJobSH() {return 'Galaxy::SGE::MakeJobSH';}
1 голос
/ 16 сентября 2009

Это почти такой же подход, как и aliased, но с использованием стандартного модуля Perl:

use constant MakeJobSH => 'Galaxy::SGE::MakeJobSH';
my $job = MakeJobSH->new();
1 голос
/ 16 сентября 2009

aliased хорошо работает, когда вы хотите влиять только на вызовы из пакетов, которые явно запрашивают псевдонимы. Если вы хотите глобальное наложение одного пространства имен на другое, используйте Package :: Alias ​​.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...