Nie mogę znaleźć wyjaśnienia, jak polimorfizm działa w Perlu. Rozumiem, co oznacza polimorfizm, ale staram się dowiedzieć, jak to działa wewnętrznie w Perlu. Czy ktoś może wskazać mi jakąś dokumentację, która to wyjaśnia. Wszystkie wyszukiwania w Google, które zrobiłem daje mi przykłady tego, co polimorfizm jest w perlu, ale nie w jaki sposób perl sprawia, że działa.Jak działa polimorfizm Perla?
Odpowiedz
Po wywołaniu obiektu lub klasy, Perl sprawdza, czy ta metoda jest dostarczana bezpośrednio przez samą klasę.
Ponieważ classes are simply Perl packages, jest to po prostu kwestia sprawdzenia istnienia podprogramu &Class::method
.
Jeżeli taki podprogram zostanie znaleziony, Perl bada tablicę @ISA
w tym samym opakowaniu (tj @Class::ISA
), który zawiera listę klas bazowych dla klasy, i robi to samo sprawdzanie każdego pakietu/klasy, który pojawia się w środku.
Każda z tych klas z kolei może mieć również tablicę @ISA
, więc wyszukiwanie jest rekurencyjne.
Na koniec, jeśli metoda nie zostanie znaleziona w tej metodzie, Perl wyszuka w specjalnym pakiecie UNIVERSAL
dla podprogramu &UNIVERSAL::method
.
Niepowodzenie w tym momencie pociąga za sobą system AUTOLOAD
, ale to naprawdę wykracza poza zasadę polimorfizmu.
Niepowodzenie znalezienia odpowiedniej metody dopasowywania w dowolnym miejscu powoduje wyjątek.
To dobrze pasuje do polimorfizmu opartego na dziedziczeniu i daje pewne pojęcie o tym, co konkretnie robi Perl. Zawsze stosowałem rozdział 12.5. Dziedziczenie klas w Programming Perl jako odniesienie dla tych rzeczy.
dla Perl OOP, zawsze lubiłem "Learning Perl Objects, References and Modules" od O'Reilly: http://shop.oreilly.com/product/9780596004781.do – David
Rozdział 7 od Object Oriented Perl, Damian Conway, Manning (2000) nazywa się Polimorfizm. Dziesięć stron.
Należy jednak pamiętać, że w przypadku języka C++ lub Java lub C# lub podobnego, nie ma zbyt wiele informacji o "polimorfizmie" w języku Perl. Powiedziałbym nawet, że koncepcja polimorfizmu sprawia, że rzeczy są bardziej skomplikowane niż w Perlu.
Myślę, że mechanizmem, który powinien starać się zrozumieć programista Perl, jest sposób działania metody. Odpowiedź brzmi: pierwsze skanowanie w trybie rekursywnym z głębokościami poprzez macierze paczek o numerach @ISA
.
Przykład, zróbmy $o->bla
. Nasz $o
jest dostępny w pakiecie A
, który nie ma implementacji bla
. Ale dziedziczy po pierwszym B
, a następnie C
(@ISA = ('B', 'C')
). Zróbmy najpierw odnośnik w B
. Nie definiuje również metody. Gdyby miał klasy rodziców, kontynuowalibyśmy nasze poszukiwania. Ale tak nie jest. Tak więc teraz patrzymy na C
i na szczęście ma ona metodę, inaczej byłby to błąd wykonania, ponieważ pakiet ostatniej instancji, UNIVERSAL
, również nie definiuje bla
.
Obiekt metoda połączenia jest w zasadzie zoptymalizowane * wersja z następujących czynności:
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
pobiera nazwę klasy związanego z obiektem. Klasa jest przechowywana w zmiennej obiektu.
$ 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
opiera się na @ISA
w pakiecie $class
i @ISA
pakietów w nim wymienione.
Ponieważ nazwa klasy znajduje się w obiekcie, a Perl może sprawdzać tablicę symboli w czasie wykonywania, wirtualna tabela metod nie jest potrzebna do zapewnienia polimorfizmu.
* — Buforuje to, który pakiet udostępnia metodę $ nazwa_metody dla klasy klasa. Co więcej, z pewnością nie oblicza całego liniowego ISA z góry, ale w razie potrzeby.
Polimorfizm jest po prostu pomysłem, że obiekty różnych typów odpowiadają na wywołania metod o tej samej nazwie. Słabo napisane języki, takie jak Perl, są "niejawnie polimorficzne".
Przykładowo CGI
przedmiot, przedmiot Apache2::Request
i Plack::Request
obiektu mają sposób param
które powrotu parametry żądania HTTP. Mógłbym napisać funkcję, która akceptuje obiekt jako parametr, i wywołać metodę param
na tym obiekcie i uzyskać parametr żądania HTTP, nie wiedząc, jaki typ obiektu jest.
Języki mocno napisane nie działają w ten sposób, ponieważ ich funkcje określają typy danych swoich parametrów. Nie mogę wywołać funkcji w Javie z obiektem typu Dog
, jeśli oczekiwał on jednego z Cat
. Tak więc silnie typowane języki muszą tworzyć specjalne mechanizmy pozwalające na polimorfizm.
- 1. Jak działa ten kod Perla?
- 2. Dlaczego polimorfizm nie działa w tym przypadku?
- 3. Jak działa ten pojedynczy liniowiec Perla?
- 4. Polimorfizm w modelach Django
- 5. Operatory globalne i polimorfizm
- 6. Polimorfizm według parametru funkcji
- 7. GWT 2.4.0 RequestFactory polimorfizm
- 8. Polimorfizm i Metody statyczne
- 9. Haskell Powrót Rodzaj Polimorfizm
- 10. Jak zaimplementować rodzajowy polimorfizm w języku C#?
- 11. C++ Szablony polimorfizm przeszkodą
- 12. Rodzinny polimorfizm w Scali
- 13. Polimorfizm ze zmiennych instancji
- 14. Jak mogę sprawdzić, czy mój skrypt Perla działa pod Windows?
- 15. Polimorfizm i C#
- 16. Polimorfizm w WCF
- 17. JAXB: polimorfizm z rodzajowych
- 18. Static polimorfizm w C++
- 19. Polimorfizm i metoda przeciążenia
- 20. Metoda przeciążania i polimorfizm
- 21. generyczne interfejsy i polimorfizm
- 22. Typ Rodzina polimorfizm
- 23. Polimorfizm idź lang
- 24. Słaby polimorfizm w OCaml
- 25. Zaawansowany polimorfizm w Javie
- 26. open() wywołanie systemowe polimorfizm
- 27. Jak zaimplementować polimorfizm za pomocą std :: shared_ptr?
- 28. Profilowanie pamięci Perla i wykrywanie nieszczelności Perla?
- 29. Gwinty Perla: jak zrobić producenta?
- 30. Jak tokenizować kod źródłowy Perla?
Wewnętrzna implementacja czy składnia/użycie? – djechlin