Programowanie obiektowe w Perl nie pojawiło się od razu — pierwotnie język był proceduralny. OOP dodano poprzez wprowadzenie dynamicznych struktur opartych na hashach i pakietach. Perl nie używa wbudowanego słowa kluczowego class, jak w większości innych języków, lecz operuje pakietami i religowaniem referencji.
Pierwsza wersja OOP w Perl to po prostu pakiet eksportujący funkcje oraz struktura danych (zwykle hash), do której przez funkcję bless przypisywana jest przynależność do pakietu. Później pojawiły się moduły CPAN takie jak Moose/Mouse/Moo, implementujące pełnofunkcjonalne meta-OOP (metaklasy, atrybuty, role).
Brak jednolitego wzorca OOP prowadzi do różnorodności stylów i niekompatybilności kodu OOP między projektami. Błędy mogą wystąpić z powodu dynamicznej natury języka (błędy w nazwach, wczesne/późne wiązanie, ręczne manipulacje metodą bless).
Przykład kodu:
package Animal; sub new { my ($class, %args) = @_; bless { %args }, $class; } sub speak { my $self = shift; print "Zwierzę mówi "; } package Cat; our @ISA = ('Animal'); sub speak { my $self = shift; print "Kot miauczy "; } my $cat = Cat->new(name => 'Barsik'); $cat->speak; # Kot miauczy
Kluczowe cechy:
Co się dzieje, jeśli w new zwrócimy nie bless'owane odniesienie, a po prostu hash?
Zwrócenie nie-bless'owanego odniesienia prowadzi do tego, że dalsze wywołania metod przez->$obj stracą powiązanie z pakietem i nie znajdą wymaganej metody — wystąpi błąd krytyczny.
Jak Perl realizuje wielokrotne dziedziczenie i rozwiązywanie konfliktów metod?
Perl pozwala na wielokrotne dziedziczenie — w tablicy @ISA może być kilka pakietów. Wyszukiwanie metody odbywa się w szerokości, z lewej do prawej, po wszystkich rodzicach. W przypadku konfliktu zostanie wybrana pierwsza znaleziona metoda.
Czy można w Perl "przeblessić" (re-bless) obiekt w trakcie wykonywania i co to oznacza?
Tak, poprzez bless można zmienić przynależność obiektu do innego pakietu w czasie wykonywania. Można to wykorzystać do zmiany "typu" obiektu. Jednak istnieje ryzyko niespójności wewnętrznej zawartości obiektu z nowymi metodami.
Przykład:
bless $cat, 'Dog'; # Teraz $cat zachowuje się jak pies!
W projekcie tworzy się obiekty przez bless oczywiście nieinicializowanej tablicy, a metody oczekują odniesienia do hasha. Program zawiesza się przy wywołaniu dowolnej metody, chociaż składnia Perl pozwala na zrobienie bless na czymkolwiek.
Zalety:
Wady:
Użycie Moose i walidowanych konstruktorów, rygorystyczna typizacja atrybutów, automatyczne tworzenie metod dostępu, zwięzłe opisywanie powiązań między obiektami.
Zalety:
Wady: