2010-09-24 43 views
19

Tôi nhận được một băm băm từ một hàm khác và một số phần tử của băm băm có thể là một băm khác. Làm thế nào tôi có thể kiểm tra để xem nếu một cái gì đó là một băm?Làm thế nào tôi có thể kiểm tra rằng "cái gì" là một băm trong Perl?

+2

bản sao có thể có của [Làm cách nào để biết loại giá trị nào nằm trong biến Perl?] (Http://stackoverflow.com/questions/1731333/how-do-i-tell-what-type-of-value -is-in-a-perl-biến) – Ether

Trả lời

36

Tùy thuộc vào những gì bạn muốn, bạn sẽ cần phải sử dụng ref hoặc reftype (mà là ở Scalar::Util, một mô-đun lõi). Nếu tham chiếu là một đối tượng, ref sẽ trả về lớp của đối tượng thay vì loại tham chiếu cơ bản, reftype sẽ luôn trả về kiểu tham chiếu cơ bản.

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 Bạn có quen với từ "tf" không? Nó giống như "nếu", nhưng nhiều hơn thế. –

+1

Vì vậy, một phiên bản mạnh mẽ hơn nếu? Có phiên bản yếu hơn không? –

+1

@brain d foy Có, có "ɨf". –

10

Sử dụng ref chức năng:

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

Thử nghiệm này không hoạt động đối với các đối tượng giống như băm: '$ r = {}; ban phước $ r," không thành công "; in ref $ r' – mob

+4

Tôi không nghĩ vi phạm đóng gói đối tượng là một ý tưởng tốt. –

+0

Ngoài ra còn có một số tích cực sai ở đây. '$ array = []; ban phước cho mảng $, 'HASH'; print ref $ array; 'in' HASH'. Không phải là bạn nên làm điều này. –

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

* qua overload

Bạn có lẽ không cần người cuối cùng, mặc dù.

thấy Params::Util

+2

'Params :: Util :: _ HASHLIKE' gọi' Scalar :: Util :: reftype', nhưng nó cũng kiểm tra xem đối số của nó có đang quá tải toán tử băm - dereferencing hay không. phát hiện các đối tượng có thể giả vờ là hashrefs ngay cả khi chúng không thực sự là hashrefs. – mob

+0

@mobrule: Vâng, tôi biết. Tôi chỉ nghĩ rằng trình bày hai lựa chọn sẽ đưa anh ta đến liên kết để xem sự khác biệt. Tôi đã thêm một ghi chú nói rằng có lẽ anh ấy không cần nó. – Axeman

5

Tôi luôn sử dụng isa, nhưng nếu điều đang được thử nghiệm không phải là một đối tượng (hoặc có thể không phải là một đối tượng), bạn cần phải gọi nó như chức năng UNIVERSAL::isa:

if (UNIVERSAL::isa($var, 'HASH')) { ... } 
Các vấn đề liên quan