perl - 为什么有些用户在 Perl 中引用类名?
问题描述
查看Type::Tiny
,我看到调用中的类名在Type::Tiny->new
官方文档中被引用,
my $NUM = "Type::Tiny"->new(
name => "Number",
constraint => sub { looks_like_number($_) },
message => sub { "$_ ain't a number" },
);
为什么是这样?这仅仅是风格吗?这种做法是否有任何性能影响?
解决方案
举一个更简单的例子
package Foo { sub new { die 7 } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();
在上面的示例中,常量Foo
解析为“Bar”,因此调用"Bar"->new
not "Foo"->new
。你如何阻止子程序解析?你可以引用它。
"Foo"->new();
至于性能影响,使用字符串而不是裸词不会使事情变得更糟。我已经确认生成的 optreeO=Deparse
是相同的。因此,作为一般规则,如果您重视正确性,似乎最好引用类名。
这在 Programming Perl 中提到,(遗憾的是在间接方法调用的上下文中)
...所以我们会告诉你,只要有两件事是真的,你几乎总是可以用一个简单的类名逃脱。首先,没有与类同名的子程序。(如果您遵循子例程名称(如以
new
小写开头)和类名(如以ElvenRing
大写开头)的约定,这绝不是问题)。二、类被加载了一个use ElvenRing; require ElvenRing;
这些声明中的任何一个都确保 Perl 知道
ElvenRing
是一个模块名,这会强制new
将类名之前的任何裸名ElvenRing
解释为方法调用,即使您碰巧new
在当前包中声明了自己的子例程。
而且,这是有道理的:只有当您的子例程(通常是小写字母)与类(通常是大写字母)具有相同的名称时,才会发生这种混淆。仅当您违反上述命名约定时,才会发生这种情况。
tldr; 如果你知道它们并且你重视正确性而不是混乱,那么引用你的类名可能是一个好主意。
旁注:或者,您可以通过在函数末尾附加 a::
来停止将裸词解析为函数,例如在上面的Foo::->new
.
感谢reddit 上的 Ginnz 向我指出这一点,并感谢Toby Inkster 的评论(尽管在第一次阅读时对我来说没有意义)。
推荐阅读
- javascript - 创建分组列垫表
- android - Service 和 ViewModel 之间的 MVVM 通信
- continuous-integration - Gerrit Checks 插件 - 如何使用 API 创建/更新检查器以进行 gerrit 更改
- r - 如何在 R 中的特定 x 值上绘制箱线图?
- java - 关于 Java Runtime.getRuntime().exec(command) 的不完整输出
- javascript - 如何显示新添加的数据?
- git - Tags trigger not working in azure pipelines
- powershell - 使用 PowerShell 脚本输出的注册表键值匹配字符串值
- android - Azure Pipeline 基于指定的 android 风格运行任务
- ruby - 新 Stripe Checkout 的单元测试