为什么有些用户在Perl中引用类名?

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)

为什么是这样?这仅仅是样式吗?这种做法是否会对性能产生影响?

Eva*_*oll 7

举一个简单的例子

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开始大写)将永远不会出现问题。第二,该类已加载以下内容之一

use ElvenRing;
require ElvenRing;
Run Code Online (Sandbox Code Playgroud)

这些声明中的任何一个都可以确保Perl知道ElvenRing是一个模块名称,即使您在当前包中恰好声明了自己的子例程,也可以将诸如new类名之前的任何裸名都强制ElvenRing解释为方法调用new

而且,这是有道理的:仅当您的子例程(通常为小写)与类具有相同的名称(通常为大写)时,才会发生混淆。仅当您违反上述命名约定时,才会发生这种情况。

tldr; 如果您知道类名并且重视正确性而不是混乱,那么最好引用类名。

旁注:或者,您可以通过在功能::的末尾附加a 来停止对某个功能的裸字解析,例如在上文中Foo::->new


感谢Ginnz在reddit上向我指出的这一点,并感谢Toby Inkster的评论(尽管对我而言初读没有意义)。

  • 或从我从池上中学到的“ Foo ::-> new”。 (2认同)