Eva*_*oll 10 perl coding-style classname bareword
看一下Type::Tiny,我看到对的调用中的类名在Type::Tiny->new官方文档中被引用,
my $NUM = "Type::Tiny"->new(
name => "Number",
constraint => sub { looks_like_number($_) },
message => sub { "$_ ain't a number" },
);
Run Code Online (Sandbox Code Playgroud)
为什么是这样?这仅仅是样式吗?这种做法是否会对性能产生影响?
举一个简单的例子
package Foo { sub new { die 7 } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,常量Foo解析为“ Bar”,因此该调用"Bar"->new不是"Foo"->new。如何停止解决子程序?您可以引用它。
"Foo"->new();
Run Code Online (Sandbox Code Playgroud)
至于性能含义,使用字符串而不是裸字不会使情况变得更糟。我已经确认生成的optree O=Deparse是相同的。因此,作为一般规则,如果您重视正确性,似乎最好引用Classnames。
在Perl编程中对此进行了提及(在间接方法调用的上下文中很可悲)
...因此,我们将告诉您,只要有两件事是对的,您几乎总是可以使用裸类名。首先,没有与该类同名的子例程。(如果遵循惯例,则子例程名称(例如
new开始小写)和类名称(例如ElvenRing开始大写)将永远不会出现问题。第二,该类已加载以下内容之一Run Code Online (Sandbox Code Playgroud)use ElvenRing; require ElvenRing;这些声明中的任何一个都可以确保Perl知道
ElvenRing是一个模块名称,即使您在当前包中恰好声明了自己的子例程,也可以将诸如new类名之前的任何裸名都强制ElvenRing解释为方法调用new。
而且,这是有道理的:仅当您的子例程(通常为小写)与类具有相同的名称(通常为大写)时,才会发生混淆。仅当您违反上述命名约定时,才会发生这种情况。
tldr; 如果您知道类名并且重视正确性而不是混乱,那么最好引用类名。
旁注:或者,您可以通过在功能::的末尾附加a 来停止对某个功能的裸字解析,例如在上文中Foo::->new。
感谢Ginnz在reddit上向我指出的这一点,并感谢Toby Inkster的评论(尽管对我而言初读没有意义)。