2008-08-14 43 views
18

在Perl中,一个对象只是一个对任何已被祝福到特定类的基本Perl数据类型的引用。当您在未引用的引用上使用ref()函数时,会被告知参考指向哪些数据类型。但是,当您在祝福的引用上调用ref()时,会返回引用已被祝福的包的名称。如何确定Perl中受祝福的引用的类型?

我想知道有福参考的实际基础类型。我怎样才能确定这一点?

回答

18

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); 
2

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

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

这是一个代码片段来证明这一点..(万一它是任何人使用)。

 
$> perl -e 'use strict; use warnings "all"; my $x = [1]; bless ($x, "ABC::Def"); use Data::Dumper; print Dumper $x; print ref($x) . "\n"; use Scalar::Util "reftype"; print reftype($x) . "\n"'` 

输出:

 
$VAR1 = bless([ 
       1 
       ], 'ABC::Def'); 
ABC::Def 
ARRAY 
+3

对象往往是实现为哈希引用,但它不是必需的。一个对象可以是任何引用类型。 – 2008-11-28 18:34:36

6

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

+0

同意,我知道有人会发表评论。我真的只需要这个,而试图找出模块创建的结构,所以我可以修改模块。我想从结构中的任何哈希中删除特定的键,因为它们包含原始JPEG。 – 2008-09-09 11:53:05

+2

后来我发现我可以使用Data :: Dumper :: sortkeys来过滤这些数据,所以Data :: Dumper不会产生兆字节的二进制输出。 – 2008-09-09 11:55:26