当它们都属于包Foo时,sub Foo :: bar {}和子条{}之间有什么区别?

时间:2014-07-22 09:02:13

标签: perl

假设我们有这样的代码

package Foo;
sub bar {
    say 'hi';
}

和这个

package Foo;
sub Foo::bar {
    say 'hi';
}

我认为它们是等价的,所以我们可以这样做

Foo->bar();

我们是否使用完全限定名称定义方法。但是,在某些情况下,它们确实不同。例如,在perldoc -f require给出的示例中,方法INC必须使用包名称进行完全限定:

# In Foo.pm
package Foo;
sub new { ... }
sub Foo::INC {
    my ($self, $filename) = @_;
    ...
}
# In the main program
push @INC, Foo->new(...);

如果我们没有完全限定方法名称,则会发生编译时错误。那么,完全限定名称和没有包名称之间的区别是什么?

2 个答案:

答案 0 :(得分:6)

导致@main::INC可以@INC全局访问的机制也会导致sub INC { }表示sub main::INC { }

引用perlvar

  

以数字,控制字符或标点符号开头的Perl标识符不受package声明的影响,并且始终强制位于包main中;他们也免除strict 'vars'错误。其他一些名字也可以通过以下方式获得豁免:

ENV STDIN
INC STDOUT
ARGV STDERR
ARGVOUT
SIG

  

如果我们没有完全限定方法名称,则会发生编译时错误。

哼...它不会做你想做的事,但它也不会造成编译时错误。

$ perl -ce'
    package Foo;
    sub new { ... }
    sub INC {
        my ($self, $filename) = @_;
        ...
    }

    push @INC, Foo->new("...");
'
-e syntax OK

答案 1 :(得分:2)

perldoc -f require说明为何如此:

  

如果钩子是一个对象,它必须提供一个将如上所述调用的INC方法,第一个参数是对象本身。 (请注意,您必须完全限定子名称,因为不合格的“INC”总是强制进入“main”包。)

因此,如果您退出包装限定符,就好像写了sub main::INC {}一样。我无法告诉你为什么会发生这种情况,但我猜这是解释器中的特殊情况之一。