Я пишу модуль Perl Galaxy::SGE::MakeJobSH
с OO.
Я хочу использовать MakeJobSH->new()
вместо Galaxy::SGE::MakeJobSH->new()
или какие-то другие короткие имена. Как я могу это сделать?
Я пишу модуль Perl Galaxy::SGE::MakeJobSH
с OO.
Я хочу использовать MakeJobSH->new()
вместо Galaxy::SGE::MakeJobSH->new()
или какие-то другие короткие имена. Как я могу это сделать?
Вы можете предложить своим пользователям использовать модуль 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__ };
Конечно, вы, вероятно, захотите выбрать только один из этих методов. Я просто объединил их, чтобы избежать дублирования примеров.
aliased
был частью стандартного дистрибутива.
- person Chris Lutz; 16.09.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();
Вы также можете сделать то же самое на уровне приложения, если хотите написать одну программу и позволить пользователям выбирать класс через конфигурацию.
Спасибо cjm.
Я просто выбираю встроенный псевдоним.
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(MakeJobSH);
sub MakeJobSH() {return 'Galaxy::SGE::MakeJobSH';}
aliased хорошо работает, когда вы хотите влиять только на вызовы из пакетов, которые явно запрашивают псевдоним. Если вы хотите использовать глобальный псевдоним одного пространства имен для другого, вместо этого используйте Package::Alias. .
Это почти тот же подход, что и aliased
, но с использованием стандартного модуля Perl:
use constant MakeJobSH => 'Galaxy::SGE::MakeJobSH';
my $job = MakeJobSH->new();