Geschichte der Frage:
OOP in Perl basiert auf Paketen (package) und der Verknüpfung von Referenzen durch die Funktion bless. Die Vererbung erfolgt durch das Array @ISA, das automatisch bestimmt, in welchen Paketen Perl nach Methoden suchen wird. Der Suchmechanismus implementiert die sogenannte MRO (method resolution order).
Problem:
Chaotische Verwaltung des Arrays @ISA und die Verwendung von SUPER ohne Verständnis der Methodensuche führen oft zu Fehlern, doppelten Aufrufen oder der Unmöglichkeit, die gewünschte Funktionalität zu überschreiben. Die Verwendung von AUTOLOAD erfordert Kontrolle, um Fallen endloser Suchschleifen zu vermeiden.
Lösung:
Beispielcode:
package Animal; sub speak { print "Animal speaks "; } package Dog; our @ISA = qw(Animal); sub speak { print "Dog barks! "; shift->SUPER::speak(); # Aufruf der Elternmethode } my $dog = bless {}, 'Dog'; $dog->speak;
Schlüsselfunktionen:
Wenn in der Vererbungskette mehrere Eltern-Pakete mit denselben Methodennamen vorhanden sind, welche wird aufgerufen?
Die Suche erfolgt von links nach rechts (in der Reihenfolge, wie sie in @ISA angegeben sind), die erste gefundene Methode wird aufgerufen.
Was passiert, wenn eine bestimmte Methode im gesamten Vererbungbaum fehlt, und AUTOLOAD nur bei einem der Eltern definiert ist?
Perl ruft AUTOLOAD nur für die Klasse auf, in der es zuerst in der Methodensuchkette gefunden wird. Weitere AUTOLOADs werden nicht ausgeführt, wenn sie nicht vorher in @ISA auftreten.
Kann die Reihenfolge der Methoden-Suche zur Laufzeit geändert werden?
Technisch ist es möglich, das Array @ISA zur Laufzeit zu ändern, dies führt jedoch zu Fragilität und schwer nachvollziehbaren Fehlern. Dieser Ansatz wird nur für spezifische Fälle empfohlen.
Mehrere Elternklassen mit denselben Methodennamen werden verwendet, ihre Reihenfolge in @ISA verändert sich unvorhersehbar manuell, Methoden rufen SUPER auf, was zu endloser Rekursion führt.
Vorteile:
Nachteile:
Änderungen nur durch explizite Deklaration von @ISA, und bei Bedarf an Mehrfachvererbung — Verwendung spezialisierter Module wie mro::Concise oder Class::C3.
Vorteile:
Nachteile: