2012-06-13 40 views
5

Tôi không thể tìm ra giải thích về cách đa hình hoạt động trong Perl. Tôi hiểu những gì đa hình có nghĩa là nhưng tôi đang cố gắng tìm ra cách thức nó hoạt động bên trong perl. Ai đó có thể chỉ cho tôi một số tài liệu giải thích nó. Tất cả các tìm kiếm google tôi đã làm cho tôi ví dụ về những gì đa hình trong perl nhưng không phải như thế nào perl làm cho nó hoạt động.Perl đa hình hoạt động như thế nào?

+0

Thực hiện nội bộ hoặc cú pháp/sử dụng? – djechlin

Trả lời

14

Khi một method is invoked trên một đối tượng hoặc lớp học, Perl sẽ xem liệu phương thức đó có được cung cấp trực tiếp bởi chính lớp đó hay không.

classes are simply Perl packages, nó chỉ đơn giản là vấn đề tìm kiếm sự tồn tại của chương trình con &Class::method.

Nếu không có chương trình con như vậy được tìm thấy, Perl xem xét @ISA mảng trong cùng một gói (ví dụ: @Class::ISA), trong đó có một danh sách các lớp cơ sở cho các lớp, và làm việc kiểm tra tương tự cho mỗi gói/lớp xuất hiện trong đó.

Mỗi lớp trong số đó cũng có thể có một mảng @ISA, do đó tìm kiếm sẽ đệ quy.

Cuối cùng, nếu phương pháp được tìm thấy ở đâu đó theo phương pháp này, Perl sẽ tìm trong gói đặc biệt UNIVERSAL cho chương trình con &UNIVERSAL::method.

Lỗi tại thời điểm này tiếp tục gọi hệ thống AUTOLOAD, nhưng điều đó thực sự vượt ra ngoài nguyên tắc đa hình.

Không tìm thấy phương thức đối sánh phù hợp ở bất kỳ đâu có ngoại lệ.

0

Điều này cũng phù hợp với đa hình dựa trên di sản và cung cấp cho một số ý tưởng về những gì Perl làm cụ thể. Tôi đã luôn luôn sử dụng chương 12.5. Thừa kế lớp trong Programming Perl làm tài liệu tham khảo cho những điều này.

+0

cho Perl OOP, tôi luôn thích "Tìm hiểu các đối tượng Perl, Tài liệu tham khảo và Mô-đun" từ O'Reilly: http://shop.oreilly.com/product/9780596004781.do – David

7

Chương 7 từ Object Oriented Perl, Damian Conway, Manning (2000) được gọi là Đa hình. Mười trang.

Xin lưu ý, tuy nhiên, trong trường hợp bạn đến từ C++ hoặc Java hoặc C# hoặc tương tự, không có quá nhiều điều cần biết về "đa hình" trong Perl. Tôi thậm chí còn nói khái niệm đa hình làm cho mọi thứ trở nên phức tạp hơn trong Perl.

Tôi nghĩ cơ chế mà một lập trình viên của Perl nên cố gắng hiểu là cách tra cứu phương thức hoạt động. Câu trả lời là: quét đệ qui theo chiều sâu đầu tiên thông qua các mảng gói @ISA.

Ví dụ, hãy làm $o->bla. $o của chúng tôi được ưu tiên vào gói A, không được triển khai bla. Nhưng nó kế thừa từ B đầu tiên và sau đó C (@ISA = ('B', 'C')). Vì vậy, chúng ta hãy tìm kiếm trong B đầu tiên. Nó cũng không định nghĩa phương thức. Nếu nó có các lớp cha mẹ, chúng tôi sẽ tiếp tục tra cứu ở đó. Nhưng nó không. Vì vậy, bây giờ chúng ta nhìn vào C, và may mắn thay nó có phương pháp, nếu không đó sẽ là một lỗi thời gian chạy, bởi vì gói cuối cùng, UNIVERSAL, cũng không xác định bla.

4

Một phương pháp đối tượng gọi về cơ bản là một tối ưu hóa * Phiên bản các nội dung sau:

my $class = ref($_[0]); 
my @isa = mro::get_linear_isa($class); 
for my $pkg (@isa) { 
    if (exists(&{$pkg.'::'.$method_name})) { 
     return &{$pkg.'::'.$method_name}; 
    } 
} 

ref được tên của lớp liên kết với các đối tượng. Lớp được lưu trữ trong biến của đối tượng.

$ perl -MDevel::Peek -e'my $o = {}; Dump($o); bless($o, "SomeClass"); Dump($o);' 
SV = IV(0x9e4ae0c) at 0x9e4ae10 
    REFCNT = 1 
    FLAGS = (PADMY,ROK) 
    RV = 0x9e317d0 
    SV = PVHV(0x9e36808) at 0x9e317d0 
    REFCNT = 1 
    FLAGS = (SHAREKEYS) 
    ARRAY = 0x0 
    KEYS = 0 
    FILL = 0 
    MAX = 7 
    RITER = -1 
    EITER = 0x0 
SV = IV(0x9e4ae0c) at 0x9e4ae10 
    REFCNT = 1 
    FLAGS = (PADMY,ROK) 
    RV = 0x9e317d0 
    SV = PVHV(0x9e36808) at 0x9e317d0 
    REFCNT = 1 
    FLAGS = (OBJECT,SHAREKEYS)  <---- 
    STASH = 0x9e323d0 "SomeClass" <---- 
    ARRAY = 0x0 
    KEYS = 0 
    FILL = 0 
    MAX = 7 
    RITER = -1 
    EITER = 0x0 

get_linear_isa được dựa trên @ISA trong gói $class, và @ISA các gói có tên trong đó.

Vì tên lớp nằm trong đối tượng và vì Perl có thể kiểm tra bảng biểu tượng của nó tại thời gian chạy, nên không có bảng phương thức ảo để cung cấp đa hình.

* — Nó lưu trữ gói nào cung cấp phương thức $ method_name cho lớp $ class. Ngoài ra, nó chắc chắn không tính toán toàn bộ tuyến tính ISA trả trước, nhưng khi cần thiết.

1

Đa hình chỉ đơn giản là ý tưởng rằng các đối tượng của các loại khác nhau phản hồi các cuộc gọi phương thức có cùng tên. Các ngôn ngữ được nhập sai, chẳng hạn như Perl, là "đa hình ngầm".

Ví dụ: đối tượng CGI, đối tượng Apache2::Request và đối tượng Plack::Request đều có phương thức param sẽ trả về tham số của yêu cầu HTTP. Tôi có thể viết một hàm chấp nhận một đối tượng làm tham số và gọi phương thức param trên đối tượng đó và nhận tham số yêu cầu HTTP mà không biết loại đối tượng đó là gì.

Ngôn ngữ được nhập mạnh không hoạt động theo cách này bởi vì chức năng của chúng chỉ định kiểu dữ liệu của thông số của chúng. Tôi không thể gọi một hàm trong Java với đối tượng thuộc loại Dog nếu nó đang mong đợi một trong số Cat. Vì vậy, các ngôn ngữ được đánh máy mạnh mẽ phải tạo ra các cơ chế đặc biệt để cho phép đa hình.

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