Perl to dynamiczny język, wspierający prototypowe PO oparte na haszach i pakietach. Do tworzenia obiektu zazwyczaj używa się bless:
package Animal; sub new { my ($class, %args) = @_; return bless { %args }, $class; } sub speak { print "Zwierzę wydaje dźwięk "; } package Dog; use parent 'Animal'; # lub our @ISA = ('Animal') sub speak { print "Hav! "; } my $dog = Dog->new(name => 'Rex'); $dog->speak; # Wyświetli: Hav!
Tutaj konstruktor new tworzy hasz z danymi obiektu i łączy go z klasą. Metody są deklarowane jak zwykłe subprogramy. Dziedziczenie jest możliwe przez @ISA lub moduł parent/base. PO w Perl jest elastyczne, ale nie rygorystyczne, co otwiera dodatkowe możliwości i subtelności.
Jak najlepiej zrealizować prywatne właściwości/metody obiektu w Perl, biorąc pod uwagę brak składni private/protected?
Odpowiedź: Nie ma wbudowanego mechanizmu, jednak prywatność osiąga się przez leksykalne zmienne poza pakietem lub umowy nazwowe (_private). Na przykład:
package Car; my $secret = 'ukryte'; # prywatne dla pakietu sub _private { ... } # umowa: nie wywoływać z zewnątrz
Takie podejście nie chroni przed dostępem, ale jest uważane za standard.
Historia
W projekcie zdefiniowano obiekt, który zawierał tablicę odniesień do innych obiektów. Programiści zapominali wywoływać metody jako $obj->method, wywołując je jako method($obj), co prowadziło do nieoczekiwanych rezultatów, zwłaszcza przy dziedziczeniu i nadpisywaniu metod – niewłaściwie określano klasę i wywoływano metody rodzica zamiast potomka.
Historia
Użycie zmiennej pakietu zamiast leksykalnej zmiennej do przechowywania stanu obiektu prowadziło do tego, że jedna zmiana stanu była odzwierciedlana we wszystkich instancjach klasy, ponieważ dane były wspólne, a nie indywidualne dla obiektu.
Historia
Niejawna praca z zmienną @ISA dla dziedziczenia, przy dynamicznym ładowaniu klas, w dużych projektach prowadziła do tego, że listy rodziców nie były aktualizowane na czas, i program niespodziewanie tracił metody lub otrzymywał niewłaściwą hierarchię.