我在阅读documentation for the attributes
module时,偶然发现了一个我从未见过的方法调用符号:
use attributes ();
attributes::->import(__PACKAGE__, \$x, 'Bent');
文档未提供此语法的解释。
在研究中,似乎Package::->method()
等价于Package->method()
和'Package'->method()
。
它似乎也等价于Package::method('Package')
,前提是该方法没有被继承。
**问题0:**使用Package::->method()
表示法有什么实际原因吗?
编辑:我发现如果你有一个常量和一个包同名,Package::->method()
调用包的方法,而Package->method()
调用常量的方法。
use constant Foo => bless {}, 'Bar'; # or just => 'Bar'
print Foo::->method(); # prints 'Foo method'
print 'Foo'->method(); # prints 'Foo method'
print Foo->method(); # prints 'Bar method'
package Foo;
sub method { 'Foo method' }
package Bar;
sub method { 'Bar method' }
奇怪的是,在use warnings
中,这个脚本会给予一个“Bareword 'Foo::' referes to nonexistent package”警告,但 * 无论如何都会执行它 *,这让我更加困惑。
更奇怪的是,在Foo::->method()
行 * 之前添加Foo::method();
行 * 可以消除“Bareword”警告 *。
**问题1:**有人能解释一下这是怎么回事吗?
对于后代来说,这是Perl v5.38.0。
1条答案
按热度按时间8wtpewkr1#
Package::->method
是一种(稍微)更安全的Package->method
写法。这在文档中有答案。How does Perl parse unquoted bare words?也是相关的。
Foo::
等同于"Foo"
,除了它还检查命名空间Foo
是否存在。Foo
也意味着"Foo"
,但只有当它不意味着其他任何东西时。当它在->
之前时,它不受约束,但在这里Foo
没有什么特别之处。因此,如果你有一个名为Foo
的sub,它将调用该sub。如果你有一个名为Foo
的常量,它将被使用。总的来说,
Foo::->method
始终表示"Foo"->method
。Foo->method
通常表示"Foo"->method
。Foo->method
也可以表示Foo()->method
。因此,我们得出了使用
Foo::
的以下原因:Foo::
,可以避免意外调用sub(包括常量)。在实践中,这种情况发生的可能性非常小。人们希望在测试中会发现这种情况。但考虑到这种情况的罕见性,如果它发生的话,可能会令人困惑。
Foo::
,您表示它不是子调用。但是当你看到
Foo->method
形式的东西时,这已经是一个假设了。当它 * 是 * 一个子调用时,发出信号更重要(例如,通过使用Foo()->method
)。Foo::
,如果您忘记加载模块,您可以获得更好的诊断。你得到
而不是
我说更好了吗?我觉得那更吵了。