Есть ли модуль или метод Perl, которые облегчают использование длинных пространств имен? - PullRequest
12 голосов
/ 18 февраля 2011

Некоторые пространства имен длинные и раздражающие.Допустим, я скачал гипотетический пакет под названием 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

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

using FooFoo::BarBar::BazBaz;

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

my $obj = Brown->new();

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

Ответы [ 2 ]

19 голосов
/ 18 февраля 2011

Прагма с псевдонимом делает это:

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'), метод с псевдонимом stash работает со строками в кавычках, как обычно:

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::} является глобальным для всех пакетов и областей. Это нормально, если вы выбираете пустой пакет для псевдонима.

0 голосов
/ 26 апреля 2019

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

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
...