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?
Trả lời
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.
Vì 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ệ.
Đ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.
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
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
.
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.
Đ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.
- 1. Tính đa hình hoạt động như thế nào trong Python?
- 2. Toán tử thay thế Perl hoạt động như thế nào?
- 3. Hệ thống luồng của Perl hoạt động như thế nào?
- 4. Lớp Perl này thực sự hoạt động như thế nào?
- 5. Pragma lib của Perl hoạt động như thế nào?
- 6. Các trường mô hình Django hoạt động như thế nào?
- 7. Máy quét màn hình hoạt động như thế nào?
- 8. Mô hình Wicket hoạt động như thế nào với chung?
- 9. PHP max_execution_time hoạt động như thế nào?
- 10. DisplacementMapFilter hoạt động như thế nào?
- 11. Flash hoạt động như thế nào?
- 12. currentPopoverFromRect hoạt động như thế nào?
- 13. Angular $ q.when hoạt động như thế nào?
- 14. WPF INotifyPropertyChanged hoạt động như thế nào?
- 15. Zmq poller hoạt động như thế nào?
- 16. Printf hoạt động như thế nào?
- 17. MenuItem.SHOW_AS_ACTION_IF_ROOM hoạt động như thế nào?
- 18. Locbaml hoạt động như thế nào?
- 19. CMake hoạt động như thế nào?
- 20. DirectX - VertexBuffer hoạt động như thế nào?
- 21. ResolveProjectReferences hoạt động như thế nào?
- 22. TouchImageView hoạt động như thế nào?
- 23. __iter__ hoạt động như thế nào?
- 24. [UIAlertView show] hoạt động như thế nào?
- 25. Traceroute hoạt động như thế nào?
- 26. ArrayAccess hoạt động như thế nào?
- 27. jQuerys $ .each() hoạt động như thế nào?
- 28. Haskell: TVar hoạt động như thế nào?
- 29. GetContentResolver() hoạt động như thế nào?
- 30. P6SPY hoạt động như thế nào?
Thực hiện nội bộ hoặc cú pháp/sử dụng? – djechlin