是否有使Perl模块或技术更容易使用长命名空间?

时间:2011-02-17 22:31:41

标签: perl namespaces

有些名称空间很长且很烦人。假设我下载了名为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'语句的模块或技术,即有没有办法

using FooFoo::BarBar::BazBaz;

然后让我做

my $obj = Brown->new();

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

2 个答案:

答案 0 :(得分:19)

aliased编译指示执行此操作:

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::}的效果在所有包和范围内都是全局的。只要你选择一个空包来别名就可以了。

答案 1 :(得分:0)

如果模块仅需要调用其类方法,则对其进行子类化是最简单的解决方案。当然,可以在运行时动态地选择Bill的位置。

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