为什么我不应该使用UNIVERSAL :: isa?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (31)

根据这个

http://perldoc.perl.org/UNIVERSAL.html

我不应该使用UNIVERSAL :: isa(),而应该使用$ obj-> isa()或CLASS-> isa()。

这意味着首先要确定某件事是否是一个参考,然后是我必须要做的这个类的参考

eval { $poss->isa("Class") }

并检查$ @和所有这些符号,否则

use Scalar::Util 'blessed';
blessed $ref && $ref->isa($class);

我的问题是为什么?UNIVERSAL :: isa出现了什么问题?对于诸如此类的东西来说,它更清洁

my $self = shift if UNIVERSAL::isa($_[0], __PACKAGE__)

查看是否在对象上调用了该函数。是否有一个很好的干净选择,不会因为&符号和可能的长行而变得繁琐?

提问于
用户回答回答于

主要的问题是,如果UNIVERSAL::isa直接调用,则会绕过任何重载的类isa。如果这些类依赖于重载行为(它们可能会这样做,否则它们不会覆盖它),那么这是一个问题。如果你isa直接调用你的祝福对象,那么isa在任何一种情况下都会调用正确的方法(如果存在,则为重载,否则为UNIVERSAL ::)。

第二个问题是,UNIVERSAL::isa只会像所有其他用户一样执行您想要的祝福参考测试isa。它对于非祝福引用和简单标量具有不同的行为。所以你的不检查是否$ref有福的例子是没有做正确的事情,你忽略了一个错误条件并使用了UNIVERSAL替代行为。在某些情况下,这可能会导致微妙的错误(例如,如果您的变量包含类的名称)。

考虑:

use CGI;

my $a = CGI->new();

my $b = "CGI";

print UNIVERSAL::isa($a,"CGI");  # prints 1, $a is a CGI object.
print UNIVERSAL::isa($b,"CGI");  # Also prints 1!! Uh-oh!!

因此,总之,请不要使用UNIVERSAL::isa...直接执行额外的错误检查并调用isa对象。

用户回答回答于

查看UNIVERSAL :: isaUNIVERSAL :: can的文档,了解为什么你不应该这样做。

简而言之,有一些重要的模块需要重写'isa'(比如Test :: MockObject),如果你把它作为一个函数来调用,你可以打破它。

我不得不说,my $self = shift if UNIVERSAL::isa($_[0], __PACKAGE__)对我来说看起来并不太干净 - 反Perl的拥护者会抱怨线路噪音。:)

扫码关注云+社区

领取腾讯云代金券