什么是“最好的”使用方式“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

perl – 使用“isa”方法的最佳方式?的更多相关文章

  1. Swift快速入门五集合

    相关文章Swift快速入门(一)第一个Swift程序Swift快速入门(二)基本数据类型Swift快速入门(三)运算符Swift快速入门(四)流程控制前言Swift提供了数组和字典两种集合类型来存储数据,Swift的数组用来存储顺序相同类型相同的类型,字典则采用kay-value的形式存储数据。修改字典字典提供了updataValue()方法来修改字典的value值,该方法会返回一个Sting?

  2. 如何在android中使用动态字符串名称访问字符串(类似于javascript中的eval)?

    我正在尝试使用动态名称访问字符串变量,具体取决于我的图库位置.要使用固定名称获取字符串的值,我使用以下哪个很好:我的字符串被命名为pic1info,pic2info,pic3info等,我想替换pic1info的静态定义以包含位置,因此传递以下字符串的内容代替上面的pic1info,以便根据当前位置返回不同的字符串:在javascript中,等价物将是eval,我确信有一种简单的方法可以做到这一点,但我无法弄清楚如何!

  3. Javascript中eval函数的使用方法与示例

    JavaScript有许多小窍门来使编程更加容易。其中之一就是eval()函数,这个函数可以把一个字符串当作一个JavaScript表达式一样去执行它。以下是它的说明

  4. Javascript学习笔记4 Eval函数

    在初学JS的时候就知道这个函数,却一直没有了解过他的用途,也一直都是睁一只眼闭一只眼,这次来深入地了解一下这个函数的作用。

  5. angularjs中的$eval方法详解

    下面小编就为大家带来一篇angularjs中的$eval方法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  6. JSON 和 JavaScript eval使用说明

    JSON (JavaScript Object Notation) 一种轻量级的数据交换格式,比 XML 更轻巧,JSON 是JavaScript 原生格式,这意味着 JavaScript 中处理 JSON 数据不需要任何 API 和工具包。

  7. 利用Python+eval函数构建数学表达式计算器

    Python 中的函数eval()​是一个非常有用的工具。在本文中,云朵君将和大家一起学习 eval() 如何工作,以及如何在 Python 程序中安全有效地使用它,需要的可以参考一下

  8. Python爬虫eval实现看漫画漫画柜mhgui实战分析

    这篇文章主要为大家介绍了Python爬虫eval实现看漫画漫画柜mhgui实战分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  9. Redis使用Eval多个键值自增的操作实例

    下面小编就为大家带来一篇Redis使用Eval 多个键值自增的操作实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. Python+eval函数实现动态地计算数学表达式详解

    Python的 eval() 允许从基于字符串或基于编译代码的输入中计算任意Python表达式。当从字符串或编译后的代码对象的任何输入中动态计算Python表达式时,此函数非常方便。本文将利用eval实现动态地计算数学表达式,需要的可以参考一下

随机推荐

  1. 数组 – Perl中有什么神奇的数组?

    在Perldocumentationforreverse中,我发现:“请注意,将数组反转到自身(如@a=reverse@a)将尽可能保留不存在的元素;即对于非魔法数组或具有EXISTS和DELETE方法的绑定数组.什么属性区分神奇和非魔法阵列?解决方法一个神奇的阵列是一个执行它的操作不仅仅是改变内容.只有内置的魔术阵列是@ISA,而且这是非常不明显的.正如句子所暗示的,魔术阵列主要是一个绑定的阵列

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

    什么是“最好的”使用方式“isa()”可靠?解决方法Scalar::Util实现明确更好.它避免了eval{}的开销,它总是导致设置一个附加变量.Scalar::Util实现更容易阅读.如果eval也失败了,我相信发生的是你在树之前向后走到eval之前的状态–这是如何实现复位状态.这带来了额外的故障开销.基准根本不是一个对象对象传递isa检查对象出现故障现象检查测试代码:我使用这是为i486-linux-gnu-thread-multi建立的perl,v5.10.1(*),以及Scalar::Util,1

  3. 在CORE :: GLOBAL中哪些Perl内置函数不能被覆盖?

    解决方法toke.c中任何值为负的值都可以被覆盖;所有其他人可能不会.你可以看源码here.例如,我们来看看第10,396行的waitpid:由于waitpid为负数,因此可能会被覆盖.grep怎么样?这是积极的,所以不能被覆盖.这意味着以下关键字不能被覆盖:chop,defined,delete,do,dump,each,else,elsif,eval,exists,for,foreach,format,glob,goto,grep,if,keys,last,local,m,map,my,next,no

  4. 如何在Perl中打印由换行符分隔的列表元素?

    什么是最简单的打印所有列表的元素以Perl中的换行符分隔的元素?解决方法在Perl5.10中:其他方式:或:或者怎么样?

  5. 使用Perl如何获取文件大小(以兆字节为单位)?

    我想以磁盘的形式获取磁盘上的文件大小.使用-s运算符给出了以字节为单位的大小,但是我将假设,然后将其除以魔术数字是一个坏主意:我应该使用只读变量来定义1024,还是有一种编程方式来获取一千字节的字节数?

  6. perl – 如何测试/分类CPAN模块的utf8正确性

    例如:File::Slurp,如果你将读取该文件您将根据命令行开关获得不同的结果,并且perl-CSDA将无法正常工作.伤心.(是的,我知道比Encode::decode(“utf8”,read_file($file,binmode=>’:raw’));将帮助,但是SAD.我的问题:>在这里任何首选方式,如何测试/分类什么CPAN模块是utf8安全/准备/正确?>这里是像Perl::Criticforutf8这样的东西–什么将检查模块源可能的utf8不正确?总结以上是DEVMAX为你收集整理的perl–如

  7. 如何删除Perl字符串中的空格?

    如果我声明一个值为’3’的变量$myString.是否有任何功能来删除返回值的空格.有点像SomeFun然后返回’3′.输出:你可以注意到’vid’=>‘0’,上面的代码从theanswer.我正在研究它.总结以上是DEVMAX为你收集整理的如何删除Perl字符串中的空格?如果觉得DEVMAX网站内容还不错,欢迎将DEVMAX网站推荐给好友。

  8. 如何在mod_perl2下运行Devel :: Cover?

    Unfortunately,Devel::Coverdoesnotyetworkwiththreads.它也不适用于prefork.在startup.pl中使用,Devel::Cover问题perl5.8.9,Apache2.2.13.我的操作系统是FreeBSD,如果重要.同样的问题是reportedforwin32.更新:PerlTrace全部输出解决方法邪恶之源似乎是Apache::DBI.

  9. 如何使用Perl中的C类?

    我有一套用C写的课.从Perl脚本中调用它们的最佳方法是什么?

  10. perl – 在Emacs中以双模式更好的缩进

    我正在使用Emacs来修改Perl和Verilog交织的代码.我正在使用two-mode-mode在两者之间切换,这样可以预期.问题是perl代码与//一行一行地表示;如下图所示:而双模式则认识到它是Perl,它是逐行的,所以缩进等在线上无意义.我想做的是使Perl代码像往常一样格式化,但忽略//;字符.有什么想法吗?我刚刚开始偷看模式文件,它们是可以理解的复杂的,所以任何提示都不会感激!

返回
顶部