2010-09-24 43 views
19

我正在接受來自另一個函數的散列的散列,並且散列的散列的一些元素可以是另一個散列。我如何測試以查看是否有散列?我如何測試「something」是Perl中的散列?

+2

[我如何知道Perl變量中的值是什麼類型?](http://stackoverflow.com/questions/1731333/how-do-i-tell-what-type-of-value -is-in-a-perl-variable) – Ether 2010-09-24 17:09:28

回答

36

取決於你想要什麼,你將需要使用refreftype(這是Scalar::Util,核心模塊)。如果引用是對象,則ref將返回對象的類而不是基礎引用類型,reftype將始終返回基礎引用類型。

if (ref $var eq ref {}) { 
    print "$var is a hash\n"; 
} 

use Scalar::Util qw/reftype/; 

if (reftype $var eq reftype {}) { 
    print "$var is a hash\n"; 
} 
+3

@brian d foy你不熟悉「tf」這個詞嗎?這就像「如果」,但更多。 – 2010-09-24 17:36:58

+1

那麼,if的更強版本呢?還有更弱的版本嗎? – 2010-09-24 17:47:20

+1

@brain d foy是的,有「ɨf」。 – 2010-09-24 18:59:56

10

使用ref功能:

ref($hash_ref) eq 'HASH' ## $hash_ref is reference to hash 
ref($array_ref) eq 'ARRAY' ## $array_ref is reference to array 

ref($hash{$key}) eq 'HASH' ## there is reference to hash in $hash{$key} 
+2

這個測試對於類似哈希的對象不起作用:'$ r = {}; bless $ r,「fail」; print ref $ r' – mob 2010-09-24 17:01:39

+4

我不認爲違反對象封裝是一個好主意。 – 2010-09-24 17:03:21

+0

這裏也有一些誤報。 '$ array = [];祝福陣列,'HASH';打印ref $ array;'打印'HASH'。不是你應該這樣做。 – 2015-12-23 18:18:01

3
use Params::Util qw<_HASH _HASH0 _HASHLIKE>; 

# for an unblessed hash with data 
print "$ref is a hash\n" if _HASH($ref); 
# for an unblessed hash empty or not 
print "$ref is a hash\n" if _HASH0($ref); 
# for a blessed hash OR some object that responds as a hash* 
print "$ref is hashlike\n" if _HASHLIKE($ref); 

*通過overload

你可能並不需要最後一個,雖然。

看到Params::Util

+2

'Params :: Util :: _ HASHLIKE'調用'Scalar :: Util :: reftype',但它也檢查它的參數是否重載散列解引用操作符 - this檢測到可以僞裝成hashrefs的對象,即使它們不是真正的hashrefs。 – mob 2010-09-24 18:48:26

+0

@mobrule:是的,我知道。我只是認爲提出兩個選擇會促使他看到這個差異。我添加了一個說明,說他可能不需要它。 – Axeman 2010-09-24 19:36:10

5

我一直使用isa,但如果被測試的東西不是一個對象(或可能不是一個對象),你需要把它作爲調用該函數UNIVERSAL::isa

if (UNIVERSAL::isa($var, 'HASH')) { ... }