如果我有一个非常长的包名,我可以通过在符号表中输入一个别名来包含该包:
BEGIN {
# Make "Alias" be an alias for "Some::Really::Long::Package";
*Alias:: = \*Some::Really::Long::Package::;
# Equivalent to:
# *main::Alias:: = \*Some::Really::Long::Package::;
}
这就是Package::Alias
之类的内容。然而,这很糟糕,因为它与main
包混淆了。如何使别名仅影响当前包,并且只能使用包中的别名?我尝试将别名定义更改为
*Short::Alias:: = \*Some::Really::Long::Package::;
但是我必须使用Short::Alias->myMethod()
而不是Alias->myMethod()
。
use strict;
use warnings;
package Some::Really::Long::Package;
sub myMethod {
print "myMethod\n";
}
package Short;
BEGIN {
# Make "Alias" be an alias for "Some::Really::Long::Package";
*Short::Alias:: = \*Some::Really::Long::Package::;
}
# I want this to work
Alias->myMethod();
package main;
# I want this to not work
Alias->myMethod();
加分如果Alias->myMethod()
和Alias::myMethod()
都在Short
包中,而不在main
中。
答案 0 :(得分:6)
由于您不想修改main
的符号表,因此您可以创建一个" package-local"别名
package Short;
use constant Alias => 'Some::Really::Long::Package'; # create alias
Alias->myMethod(); # correctly calls myMethod() of package Some::Really::Long::Package
或者
package Short;
sub Alias { Some::Really::Long::Package:: } # create alias
Alias->myMethod(); # correctly calls myMethod() of package Some::Really::Long::Package
两个示例都应按预期工作。因此,任何从包Alias->myMethod()
致电main
的尝试都会失败
找不到对象方法" myMethod"通过包" Alias" (也许你忘了加载" Alias"?)
因为符号表%main::
或%::
没有名为Alias::
的条目。
由于您在一个文件中有多个package
来电,因此您还可以创建$alias
来引用Some::Really::Long::Package
。然后,您可以将$alias
的范围限制为包Short
,以使其无法从其他位置访问:
package Short;
{
my $alias = Some::Really::Long::Package::; # create alias
$alias->myMethod(); # correctly calls myMethod() of package Some::Really::Long::Package
}
编辑(作为对编辑问题的回复):
更新的问题是:
Alias->myMethod()
和Alias::myMethod()
都可以在Short
包中使用,但不能在main
中使用吗?
我不这么认为。
有几种方法可以使用->
语法,但不能使用::
语法。这是因为perl似乎假设像Alias
这样的简单字后跟包分隔符::
代表包Alias
中的包main
:
package Short;
Alias::myMethod(); # if you call myMethod(), you actually call it ...
::Alias::myMethod(); # ... like this, which is equivalent ...
main::Alias::myMethod(); # ... to this
所有三个呼叫选项都是等效的,这表明了一个重要的事实。如果perl遇到Foo::
之类的内容,它会首先在包main
中查找而不是从当前(相对)位置查找。因此,如果我在这里没有遗漏某些内容,则无法在未将Alias::myMethod()
添加到Alias::
的情况下使用main
。
这就是
Package::Alias
之类的内容。但是,这很糟糕,因为它与main
包混淆了。
现在,我上面描述的内容也可以解释为什么像Package::Alias
这样的模块会修改你的main
包,因为似乎无法避免它。