perl – 使用“isa”方法的最佳方式?

前端之家收集整理的这篇文章主要介绍了perl – 使用“isa”方法的最佳方式?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
什么是“最好的”使用方式“isa()”可靠?换句话说,所以它可以在任何值上正确工作,而不仅仅是一个对象.

“最好的”,我的意思是缺乏未经处理的角色,以及缺乏潜在的性能问题,所以这不是一个主观问题.

This question提到了两种看起来很可靠的方法(请注意,不应该使用旧样式UNIVERSAL :: isa(),原因在于答案中记录的原因):

eval { $x->isa("Class") }
#and check $@ in case $x was not an object,in case $x was not an object

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

第一个使用eval,第二个使用B ::(至少对于Scalar :: Util的非XS风格).

如果$x是包含类名称的标量,则第一个似乎无法正常工作,如下所示,所以我倾向于#2(使用祝福),除非somoene表示不是很好的理由.

$perl5.8 -e '{use IO::Handle;$x="IO::Handle";
  eval {$is = $x->isa("IO::Handle")}; print "$is:$@\n";}'          
1:

有没有客观的原因选择这两种方法之一(或者我不知道的第三种方法),如性能,不处理某些特殊情况等等?

解决方法

Scalar :: Util实现明确更好.它避免了eval {}的开销,它总是导致设置一个附加变量.
perl -we'$@=q[foo]; eval {}; print $@'

Scalar :: Util实现更容易阅读(它不会因为代码未知的原因而死亡).如果eval也失败了,我相信发生的是你在树之前向后走到eval之前的状态 – 这是如何实现复位状态.这带来了额外的故障开销.

基准

根本不是一个对象

Rate eval   su
eval  256410/s   -- -88%
su   2222222/s 767%   --

对象传递isa检查

Rate   su eval
su   1030928/s   -- -16%
eval 1234568/s  20%   --

对象出现故障现象检查

Rate   su eval
su   826446/s   --  -9%
eval 909091/s  10%   --

测试代码

use strict;
use warnings;
use Benchmark;
use Scalar::Util;

package Foo;

Benchmark::cmpthese(
    1_000_000,{
        eval => sub{ eval{ $a->isa(__PACKAGE__) } },su => sub { Scalar::Util::blessed $a && $a->isa(__PACKAGE__) }
    }
);

package Bar;

$a = bless {};

Benchmark::cmpthese(
    1_000_000,{
        eval => sub{ eval{ $a->isa(__PACKAGE__)} },su => sub { Scalar::Util::blessed $a && $a->isa(__PACKAGE__) }
    }
);

package Baz;

$a = bless {};

Benchmark::cmpthese(
    1_000_000,{
        eval => sub{ eval{ $a->isa('duck')} },su => sub { Scalar::Util::blessed $a && $a->isa( 'duck' ) }
    }
);

我使用这是为i486-linux-gnu-thread-multi建立的perl,v5.10.1(*),以及Scalar :: Util,1.21

原文链接:https://www.f2er.com/Perl/172545.html

猜你在找的Perl相关文章