【发布时间】:2010-09-05 21:09:01
【问题描述】:
在 Perl 中,对象只是对已被赋予特定类的任何基本 Perl 数据类型的引用。当您在 unblessed 引用上使用 ref() 函数时,您会被告知引用指向的数据类型。但是,当您在祝福引用上调用 ref() 时,您将返回该引用已被祝福的包的名称。
我想知道祝福引用的实际底层类型。我如何确定这一点?
【问题讨论】:
在 Perl 中,对象只是对已被赋予特定类的任何基本 Perl 数据类型的引用。当您在 unblessed 引用上使用 ref() 函数时,您会被告知引用指向的数据类型。但是,当您在祝福引用上调用 ref() 时,您将返回该引用已被祝福的包的名称。
我想知道祝福引用的实际底层类型。我如何确定这一点?
【问题讨论】:
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
显然,您还必须检查 ARRAY 和 SCALAR 类型。自 Perl 5.003 以来,UNIVERSAL 模块(用作所有对象的基类)一直是核心的一部分。
另一种方法——简单但有点脏——是对引用进行字符串化。假设该类没有重载字符串化,您将返回类似于 Class=HASH(0x1234ABCD) 的内容,您可以对其进行解析以提取底层数据类型:
my $type = ($object =~ /=(.+)\(0x[0-9a-f]+\)$/i);
【讨论】:
您可能不应该这样做。对象的底层类型是您不应该混淆的实现细节。你为什么想知道这个?
【讨论】:
我对此的第一个想法是:“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::定义 大批【讨论】: