为什么有些用户在Perl中引用类名? [英] Why do some users quote classnames in Perl?

查看:94
本文介绍了为什么有些用户在Perl中引用类名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看 Type :: Tiny ,我看到对 Type :: Tiny-> new 的调用中的类名在官方文档中被引用,

  my $ NUM = Type :: Tiny-> new(
name => Number,
约束=> sub {looks_like_number($ _)},
message => sub { $ _不是数字},
);

为什么?这仅仅是样式吗?

解决方案

举一个简单的例子

  package Foo {sub new {die 7}}; 
包Bar {sub new {die 42}};
sub Foo { Bar }
Foo-> new();

在上面的示例中,常量 Foo 解析为 Bar,因此将其称为 Bar->新建,而不是 Foo->新建 。如何停止解决子程序?您可以引用它。

  Foo-> new(); 

对于性能含义,使用字符串而不是裸字不会使情况变得更糟。我已经确认 O = Deparse 生成的optree是相同的。因此,作为一般规则,如果您重视正确性,似乎最好引用类名。


这在Perl编程中已提及(在间接方法调用


...因此,如果有两件事是对的,我们将告诉您几乎总是可以使用裸类名称。首先,没有与该类同名的子例程。 (如果遵循惯例,子例程名称(如 new 开头为小写,类名称如 ElvenRing 开头为大写,这绝对不是问题)。其次,使用ElvenRing在该类中加载了

 之一; 
需要ElvenRing;

这两个声明均确保Perl知道 ElvenRing 是一个模块名称,它会强制在类名称 ElvenRing 之前将任何裸名(例如 new )解释为方法调用,即使您碰巧在当前包中声明了自己的 new 子例程。


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


tldr;

边注:或者,您可以通过在函数名后加上一个A来停止对裸词的解析,这可能是个好主意。 :: 到末尾,例如上面的 Foo ::-> new




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


Looking at Type::Tiny, I see that the class name in the call to Type::Tiny->new is quoted in the official docs,

my $NUM = "Type::Tiny"->new(
   name       => "Number",
   constraint => sub { looks_like_number($_) },
   message    => sub { "$_ ain't a number" },
);

Why is this? Is this mere style? Is there any performance ramifications for this practice?

解决方案

Take a simpler example

package Foo { sub new { die 7  } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();

In the above example, the constant Foo resolves to "Bar", so so this calls "Bar"->new not "Foo"->new. How do you stop the subroutine from resolving? You can quote it.

"Foo"->new();

As for the performance implication, things are not made worse by using a string rather than a bareword. I've confirmed the optree generated by O=Deparse is the same. So as a general rule, it seems it's better to quote the Classnames if you value correctness.

This is mentioned in Programming Perl, (sadly in the context of indirect method invocation)

... so we'll tell you that you can almost always get away with a bare class name, provided two things are true. First, there is no subroutine of the same name as the class. (If you follow the convention that subroutine names like new start lowercase and class names like ElvenRing start uppercase, this is never a problem). Second, the class been loaded with one of

use ElvenRing;
require ElvenRing;

Either of these declarations ensures that Perl knows ElvenRing is a module name, which forces any bare name like new before the class name ElvenRing to be interpreted as a method call, even if you happen to have declare a new subroutine of your own in the current package.

And, that makes sense: the confusion here can only happen if your subroutines (typically lowercase) have the same name as a class (typically uppercase). This can only happen if you violate that naming convention above.

tldr; it is probably a good idea to quote your classnames, if you know them and you value correctness over clutter.

Side note: alternatively you can stop resolution of a bareword to a function by affixing a :: to the end of it, for example in the above Foo::->new.


Thanks to Ginnz on reddit for pointing this out to me, and to Toby Inkster for the comment (though it didn't make sense to me on first read).

这篇关于为什么有些用户在Perl中引用类名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆