如果我有一个非常长的包名,我可以通过在符号表中创建一个条目来对该包进行别名:
BEGIN {
# Make "Alias" be an alias for "Some::Really::Long::Package";
*Alias:: = \*Some::Really::Long::Package::;
# Equivalent to:
# *main::Alias:: = \*Some::Really::Long::Package::;
}
Run Code Online (Sandbox Code Playgroud)
这就是Package::Alias你内心所做的事情.然而,这很糟糕,因为它与main包装混乱.如何使别名仅影响当前包,并且只能使用包中的别名?我尝试将别名定义更改为
*Short::Alias:: = \*Some::Really::Long::Package::;
Run Code Online (Sandbox Code Playgroud)
但后来我不得不使用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();
Run Code Online (Sandbox Code Playgroud)
奖励积分,如果双方Alias->myMethod()和Alias::myMethod()工作的Short包,而不是在main.
由于您不想修改符号表main,因此可以使用创建"包本地"别名
package Short;
use constant Alias => 'Some::Really::Long::Package'; # create alias
Alias->myMethod(); # correctly calls myMethod() of package Some::Really::Long::Package
Run Code Online (Sandbox Code Playgroud)
或者
package Short;
sub Alias { Some::Really::Long::Package:: } # create alias
Alias->myMethod(); # correctly calls myMethod() of package Some::Really::Long::Package
Run Code Online (Sandbox Code Playgroud)
这两个例子都应该按预期工作.因此,任何Alias->myMethod()从包调用的尝试main都会失败
无法通过包"别名"找到对象方法"myMethod"(也许你忘了加载"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
}
Run Code Online (Sandbox Code Playgroud)
编辑(作为对编辑问题的回复):
更新的问题是:
既可以
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
Run Code Online (Sandbox Code Playgroud)
所有三个呼叫选项都是等效的,这表明了一个重要的事实.如果perl遇到类似的东西Foo::,它会先开始查看包,main而不是从当前(相对)位置查看.所以,如果我不是在这里失去了一些东西,你不能使用Alias::myMethod()不添加Alias::到main.
这就是
Package::Alias你内心所做的事情.然而,这很糟糕,因为它与main包装混乱.
现在,我上面描述的内容也解释了为什么模块会Package::Alias修改你的main包,因为似乎没有办法避免它.