Scalar::Util 与 ref 函数

发布于 2024-10-07 12:18:09 字数 580 浏览 4 评论 0原文

内置的 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;
}

What's the difference between the built in ref($object) and Scalar::Util blessed($object)? Is one preferred over the other?

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

樱花细雨 2024-10-14 12:18:09

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

它对其他所有内容都返回 undef,包括哈希/数组引用,其中 ref() 返回 HASH/ARRAY (并且perldoc ref 中描述的一堆其他类型。要获取引用类型,您当然可以调用Scalar::Util::reftype

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

  • 如果您想要将真正的受祝福的引用与其他内容区分开来,blessed() 提供了一种比采用 ref 更简洁的方法,然后验证该值不是由 unblessed 引用返回的标准值。

    我的 $ref_type = ref($my_ref);
    打印“使用参考:”;
    如果($ref_type
           && $ref_type ne ref({})
           && $ref_type ne ref([])
           && $ref_type ne“标量”
           # 也可以使用包含 ref() 所有允许值的哈希值
           && $ref_type !~ /^(CODE|REF|GLOB|...)$) { 
        print "我是 $ref_type\n 类的对象";
    } 别的 {
        print "我是 $ref_type\n 类型的引用";
    }
    
    
    # 对比... 
    
    
    打印“使用SCALAR_UTIL:”;
    我的 $ref_type = 祝福($my_ref);
    打印 $ref_type ? “我是 $ref_type\n 类的对象”
                    :“我是一个类型的参考”。 reftype($my_ref) 。 “\n”;
    
  • 如果您需要区分受祝福的引用和不同的受祝福的引用,那么单个 ref() 调用比 blessed的组合更简洁reftype

  • 正如 Eric Strom 的评论中所指出的,两种方法之间存在实际功能差异的一个边缘情况是,当有人创建一个与 ref() 之一匹配的类时 硬编码值(例如 bless [], 'HASH' - 在这种情况下它们要么太笨,要么太聪明)。

    my $sssft = bless [], 'HASH'; # sssft = 有人_应该_受苦_为此
    ref_description_using_ref($sssft);
    ref_description_using_scalar_util($sssft);
    
    
    # 输出:
    USING REF:我是 HASH 类型的引用
    使用 SCALAR_UTIL:我是 HASH 类的对象
    

免责声明:根据文档,当参数是祝福到类中的引用时(例如,它返回类名),两者之间应该没有区别。但我还没有检查“Scalar::Util”源来确认。

According to POD, blessed() only works on blessed references (e.g. a references passed to a bless() call).

It returns undef on everything else, including hash/array refs where ref() returns HASH/ARRAY (and a bunch of other types as delineated in perldoc ref). To get reference type you can, of course call Scalar::Util::reftype.

As for whether one should be used over another, I think it depends largely on what the logic is.

  • If you only want to distinguish real blessed references from everything else, blessed() provides a more concise way than taking a ref and then verifying that the value is not on of standard ones returned by unblessed reference.

    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";
    
  • If you need fine distinctions between both blessed references and different ublessed ones, then a single ref() call is more concise than a combination of blessed and reftype.

  • One edge case where there's an actual functional difference between the two approaches, as noted in the comments by Eric Strom, is when someone creates a class which matches one of ref() hardcoded values (e.g. bless [], 'HASH' - in which case they are either Way Dumb or Way Too Clever By Half).

    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
    

DISCLAIMER: Based on documentation, there should be no difference between the two when the argument is a reference blessed into a class (e.g. it returns class name). But I haven't checked "Scalar::Util" source to confirm.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文