如果我有一个非常长的包名,我可以通过在符号表中创建一个条目来对该包进行别名:
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
包,因为似乎没有办法避免它.
归档时间: |
|
查看次数: |
415 次 |
最近记录: |