Scalar :: Util与ref函数

Dav*_* W. 7 perl perl-module

内置ref($object)和有Scalar::Util blessed($object)什么区别?一个比另一个更受欢迎吗?

use strict;
use warnings;

use Scalar::Util qw(blessed isvstring);

my $object = foo->new();

print "Object is a " . blessed($object) . "\n";
print "Object is a " . ref($object) . "\n";

my $version = 5.00.03;

print "Version is a " . ref(\$version) . "\n";
if (isvstring($version)) {
    print "Version is a VSTRING\n";
}

package foo;
sub new {
    my $class = shift;
    my $self = {};

    bless($self, $class);
    return $self;
}
Run Code Online (Sandbox Code Playgroud)

DVK*_*DVK 8

根据POD,blessed()仅适用于有福的引用(例如传递给bless()调用的引用).

它返回undef其他所有内容,包括hash/array引用ref()返回HASH/ ARRAY(以及perldoc ref中描述的一堆其他类型).要获得参考类型,您当然可以致电Scalar::Util::reftype.

至于是否应该使用另一个,我认为这在很大程度上取决于逻辑是什么.

  • 如果你只是想区分一切真正有福的引用,blessed()提供了比采取一种更简洁的方式ref,然后验证该值不是由unblessed参考返回的标准的人的.

    my $ref_type = ref($my_ref);
    print "USING REF: ";
    if (      $ref_type
           && $ref_type ne ref({})
           && $ref_type ne ref([])
           && $ref_type ne "SCALAR"
           # Could also use a hash with all allowed values of ref() instead
           && $ref_type !~ /^(CODE|REF|GLOB|...)$) { 
        print "I am an object of class $ref_type\n";
    } else {
        print "I'm a reference of type $ref_type\n";
    }
    
    
    # vs... 
    
    
    print "USING SCALAR_UTIL: ";
    my $ref_type = blessed($my_ref);
    print $ref_type ? "I am an object of class $ref_type\n"
                    : "I am a reference of type " . reftype($my_ref) . "\n";
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果你需要同时祝福引用和不同ublessed者之间的细微差别,然后单ref()呼比的组合更简洁blessedreftype.

  • 正如Eric Strom的评论中所指出的那样,两个方法之间存在实际功能差异的一个边缘情况是,当有人创建一个与ref() 硬编码值之一匹配的类时(例如bless [], 'HASH'- 在这种情况下,它们是Way Dumb或Way Too Clever)一半).

    my $sssft = bless [], 'HASH'; # sssft = someone_should_suffer_for_this
    ref_description_using_ref($sssft);
    ref_description_using_scalar_util($sssft);
    
    
    # OUTPUT:
    USING REF: I'm a reference of type HASH
    USING SCALAR_UTIL: I am an object of class HASH
    
    Run Code Online (Sandbox Code Playgroud)

免责声明:基于文档,当参数是一个被赋予类的引用时(例如它返回类名),两者之间应该没有区别.但我没有检查"Scalar :: Util"来源确认.

  • 另一方面,`Scalar :: Util :: reftype`返回底层引用类型(例如`HASH`或`GLOB`或者其他什么),即使它的参数是幸运的.基本上`reftype`和`blessed`解开了内置`ref`试图做的两件事. (4认同)