【问题标题】:How can I determine the type of a blessed reference in Perl?如何在 Perl 中确定祝福引用的类型?
【发布时间】:2010-09-05 21:09:01
【问题描述】:

在 Perl 中,对象只是对已被赋予特定类的任何基本 Perl 数据类型的引用。当您在 unblessed 引用上使用 ref() 函数时,您会被告知引用指向的数据类型。但是,当您在祝福引用上调用 ref() 时,您将返回该引用已被祝福的包的名称。

我想知道祝福引用的实际底层类型。我如何确定这一点?

【问题讨论】:

    标签: perl reference types


    【解决方案1】:

    Scalar::Util::reftype() 是最干净的解决方案。 Scalar::Util 模块在 5.7 版中添加到 Perl 核心,但可用于 CPAN 的旧版本(5.004 或更高版本)。

    您也可以使用UNIVERSAL::isa()进行探测:

    $x->isa('HASH')             # if $x is known to be an object
    UNIVERSAL::isa($x, 'HASH')  # if $x might not be an object or reference
    

    显然,您还必须检查 ARRAYSCALAR 类型。自 Perl 5.003 以来,UNIVERSAL 模块(用作所有对象的基类)一直是核心的一部分。

    另一种方法——简单但有点脏——是对引用进行字符串化。假设该类没有重载字符串化,您将返回类似于 Class=HASH(0x1234ABCD) 的内容,您可以对其进行解析以提取底层数据类型:

    my $type = ($object =~ /=(.+)\(0x[0-9a-f]+\)$/i);
    

    【讨论】:

    • 你只需要 eval { $x->isa($type) };如果那不是一个对象,那么你会返回 false。如果它不是正确的类型,你会得到假,如果它是正确的类型,你会得到真。 :)
    【解决方案2】:

    您可能不应该这样做。对象的底层类型是您不应该混淆的实现细节。你为什么想知道这个?

    【讨论】:

    • 同意,我知道有人会发表此评论。我真的只在试图找出模块正在创建的结构时才需要这个,这样我就可以修改模块。我想从结构中的任何散列中删除特定键,因为它们包含原始 JPEG。
    • 后来我发现我可以使用 Data::Dumper::sortkeys 来过滤这些数据,这样 Data::Dumper 就不会产生兆字节的二进制输出。
    【解决方案3】:

    我对此的第一个想法是:“Perl 中的对象始终是哈希引用,那么 hack 是什么?”

    但是,Scalar::Util::reftype 就是答案。感谢您在这里提出问题。

    这里有一个代码 sn-p 来证明这一点..(以防它对任何人有用)。

    $> perl -e '使用严格;使用警告“全部”; 我的 $x = [1];祝福 ($x, "ABC::Def"); 使用 Data::Dumper;打印转储器 $x; 打印参考($x)。 "\n"; 使用 Scalar::Util "reftype";打印 reftype($x) 。 "\n"'`

    输出:

    $VAR1 = 祝福([ 1 ], 'ABC::Def' ); ABC::定义 大批

    【讨论】:

    • 对象通常被实现为哈希引用,但这不是必需的。对象可以是任何引用类型。
    猜你喜欢
    • 2011-05-04
    • 1970-01-01
    • 2011-07-26
    • 2014-01-19
    • 2014-07-29
    • 2011-01-20
    • 2014-01-17
    • 2011-10-29
    • 2015-11-25
    相关资源
    最近更新 更多