Подтвердить что ты не робот

Есть ли модуль или метод Perl, который упрощает использование длинных пространств имен?

Некоторые пространства имен длинны и раздражают. Допустим, что я загрузил гипотетический пакет под названием FooFoo-BarBar-BazBaz.tar.gz, и он имеет следующие модули:

FooFoo::BarBar::BazBaz::Bill
FooFoo::BarBar::BazBaz::Bob
FooFoo::BarBar::BazBaz::Ben
FooFoo::BarBar::BazBaz::Bozo
FooFoo::BarBar::BazBaz::Brown
FooFoo::BarBar::BazBaz::Berkly
FooFoo::BarBar::BazBaz::Berkly::First
FooFoo::BarBar::BazBaz::Berkly::Second

Есть ли модуль или метод, который я могу использовать так же, как и оператор С++ 'using', т.е. есть ли способ, который я могу сделать

using FooFoo::BarBar::BazBaz;

который позволил бы мне сделать

my $obj = Brown->new();

ok $obj->isa('FooFoo::BarBar::BazBaz::Brown') ;  # true
# or...
ok $obj->isa('Brown'); # also true
4b9b3361

Ответ 1

aliased pragma делает это:

use aliased 'FooFoo::BarBar::BazBaz::Bill';

my $bill = Bill->new;

aliased является синтаксическим сахаром для

use constant Bill => 'FooFoo::BarBar::BazBaz::Bill';
# or 
sub Bill () {'FooFoo::BarBar::BazBaz::Bill'}

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

$obj->isa('FooFoo::BarBar::BazBaz::Bill')

Но константная подпрограмма должна быть голым словом:

$obj->isa(Bill);

Это похоже на ошибку, ожидающую появления.

В качестве альтернативы вы можете просто использовать встроенную поддержку Perl для псевдонимов пространства имен:

package Foo::Bar::Baz::Bill;

sub new {bless {}}

package Foo::Bar::Baz::Tom;

sub new {bless {}}

package main;

BEGIN {*FBB:: = *Foo::Bar::Baz::}  # the magic happens here

say FBB::Bill->new;  # Foo::Bar::Baz::Bill=HASH(0x80fd10)

say FBB::Tom->new;   # Foo::Bar::Baz::Tom=HASH(0xfd1080)

В отношении требования ->isa('shortname') метод псевдонимов с псевдонимом работает со строками с кавычками, как обычно:

my $obj = FBB::Bill->new;

say $obj->isa('FBB::Bill');           # prints 1
say $obj->isa('Foo::Bar::Baz::Bill'); # prints 1

Эффект псевдонима времени компиляции BEGIN {*short:: = *long::package::name::} является глобальным для всех пакетов и областей. Это нормально, пока вы выбираете пустой пакет для псевдонимов.

Ответ 2

Если модулю нужно вызывать только методы класса, тогда подклассы - это самое простое решение. Конечно, это можно сделать динамически во время выполнения, чтобы выбрать, куда отправится Билл.

push @Bill::ISA, "FooFoo::BarBar::BazBaz::Bill";
print Bill->isa("FooFoo::BarBar::BazBaz::Bill");
1

sub FooFoo::BarBar::BazBaz::Bill::yo {
  print "FooFoo::BarBar::BazBaz::Bill here\n";
}

Bill->yo
FooFoo::BarBar::BazBaz::Bill here