6

如果我有一个非常长的包名,我可以通过在符号表中创建一个条目来为该包起别名:

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.

4

1 回答 1

7

由于您不想修改 的符号表main,您可以创建一个“包本地”别名

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显然都会失败

无法通过包“Alias”定位对象方法“myMethod”(也许您忘记加载“Alias”?)

因为符号表%main::%::没有这样的条目称为Alias::.


由于您package在一个文件中有多个调用,因此您还可以创建$alias以引用Some::Really::Long::Package. 然后您可以将范围限制为$aliasShort,使其无法从其他地方访问:

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包,因为似乎没有办法避免它。

于 2016-10-12T04:54:09.907 回答