2008-08-14 28 views
18

Trong Perl, một đối tượng chỉ là một tham chiếu đến bất kỳ kiểu dữ liệu Perl cơ bản nào đã được chuyển vào một lớp cụ thể. Khi bạn sử dụng hàm ref() trên một tham chiếu không bị chặn, bạn được cho biết loại tham chiếu trỏ đến kiểu dữ liệu nào. Tuy nhiên, khi bạn gọi ref() trên một tham chiếu may mắn, bạn được trả về tên của gói mà tham chiếu đã được ban phước vào.Làm cách nào để xác định loại tham chiếu được ưu tiên trong Perl?

Tôi muốn biết loại cơ bản thực sự của tham chiếu may mắn. Làm thế nào tôi có thể xác định điều này?

Trả lời

18

Scalar::Util::reftype() là giải pháp sạch nhất. Mô-đun Scalar::Util đã được thêm vào lõi Perl trong phiên bản 5.7 nhưng có sẵn cho các phiên bản cũ hơn (5.004 hoặc mới hơn) từ CPAN.

Bạn cũng có thể thăm dò với 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 

Rõ ràng, bạn cũng sẽ phải kiểm tra ARRAYSCALAR loại. Module UNIVERSAL (phục vụ như là lớp cơ sở cho tất cả các đối tượng) đã là một phần cốt lõi kể từ Perl 5.003.

Một cách khác - dễ dàng nhưng hơi bẩn - là phải chỉnh sửa tham chiếu. Giả sử rằng lớp đã không bị quá tải stringification bạn sẽ liên hệ lại một cái gì đó giống như Class=HASH(0x1234ABCD), mà bạn có thể phân tích để trích xuất các kiểu dữ liệu cơ bản:

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

Bạn chỉ muốn eval {$ x-> isa ($ type)}; Nếu đó không phải là một đối tượng, bạn sẽ trở lại sai. Nếu đó không phải là loại phù hợp, bạn sẽ bị sai và nếu đó là loại phù hợp, bạn sẽ thành hiện thực. :) –

2

Và suy nghĩ đầu tiên của tôi về điều này là: "Các đối tượng trong Perl luôn là hàm băm, vì vậy những gì mà hack?"

Nhưng, Scalar :: Util :: reftype là câu trả lời. Cảm ơn bạn đã đặt câu hỏi ở đây.

Dưới đây là một đoạn mã để chứng minh điều này .. (trong trường hợp nó là của bất kỳ sử dụng cho bất cứ ai).

 
$> 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"'` 

Output:

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

Đối tượng thường được thực hiện như tài liệu tham khảo băm, nhưng nó không phải là một yêu cầu. Một đối tượng có thể là bất kỳ kiểu tham chiếu nào. –

6

Bạn có lẽ không nên làm điều này. Loại cơ bản của một đối tượng là một chi tiết triển khai mà bạn không nên gây rối. Tại sao bạn muốn biết điều này?

+0

Đồng ý, và tôi biết ai đó sẽ đưa ra nhận xét này. Tôi thực sự chỉ cần điều này trong khi cố gắng tìm ra cấu trúc mà một mô-đun đã tạo để tôi có thể sửa đổi mô-đun. Tôi muốn xóa một khóa cụ thể từ bất kỳ băm nào trong cấu trúc vì chúng chứa một JPEG thô. –

+2

Sau đó tôi phát hiện ra rằng tôi có thể sử dụng Data :: Dumper :: sortkeys để lọc dữ liệu này để Data :: Dumper không tạo ra megabyte đầu ra nhị phân. –

Các vấn đề liên quan