W Perl obiekty są realizowane poprzez "blessing" odniesień do standardowych struktur danych (tablice, hashe, skalarne). Historycznie OOP w Perl opiera się na dostępie do hasha, gdzie klucze to nazwy atrybutów, a wartości to same dane. Takie podejście zapewnia elastyczność, ale wymaga dyscypliny: język nie wprowadza ścisłej enkapsulacji i modyfikatorów dostępu — wszystko opiera się na umowach.
Problem: Bez wyraźnych ograniczeń dostęp do atrybutów jest możliwy z dowolnego kodu; łatwo złamać inwarianty obiektu, pomylić przestrzenie nazw, popełnić błąd w dziedziczeniu.
Rozwiązanie — ściśle przestrzegać umów: ukrywać dane wewnętrzne poprzez umowę (na przykład, za pomocą podkreślenia), w miarę możliwości korzystać z metod dostępowych, a dla bardziej złożonych zadań stosować standardowe moduły Moose, Moo, Class::Accessor itp.
Przykład kodu:
package Animal; sub new { my $class = shift; my $self = { _name => shift }; bless $self, $class; return $self; } sub get_name { $_[0]->{_name} } package Dog; use parent 'Animal'; sub bark { print "Woof! "; } my $dog = Dog->new("Buddy"); print $dog->get_name; $dog->bark;
Kluczowe cechy:
Czy można stworzyć obiekt Perl bez użycia bless?
Odpowiedź: Nie, tylko bless zamienia zwykłe odwołanie w obiekt, rozumiany przez metodę ->
Po co potrzebne są base/parent i jaka jest różnica z @ISA?
Odpowiedź: @ISA — to tablica, która wskazuje na klasy bazowe. base/parent automatyzują pracę z @ISA i czynią dziedziczenie modułów bezpieczniejszym: zapobiegają podwójnemu dziedziczeniu i dają dodatkowe kontrole.
Czy podrzędna klasa nadpisze metody klasy nadrzędnej, jeśli są zdefiniowane o tej samej nazwie?
Odpowiedź: Tak, jeśli w podrzędnej klasie zdefiniowana jest metoda o tej samej nazwie, '->' wybierze ją w pierwszej kolejności — działa klasyczne "method overriding".
W module Animal dane są przechowywane w otwartych atrybutach, do których dostęp następuje bezpośrednio. Ktoś nieświadomie zmienia wartość pola z zewnątrz — obiekt przechodzi w niekonsekwentny stan.
Zalety:
Wady:
Moduł używa akcesorów, wszystkie wewnętrzne pola zaczynają się od _, jest wyraźna specyfikacja — praca z danymi odbywa się tylko przez metody get/set, wprowadzone są kontrole w set.
Zalety:
Wady: