Thread AUTOLOAD ist übler Hack (13 answers)
Opened by Muffi at 2015-01-13 10:43

rosti
 2015-01-13 16:02
#179213 #179213
User since
2011-03-19
3196 Artikel
BenutzerIn
[Homepage]
user image
Quote
Entweder Autoloader benutzen oder eine sub AUTOLOAD manuell (ohne Autoloader) schreiben.


Ja, das steht seit Jahren in dicken Büchern ;)

Aus Artikel:
Quote
If the object's class hierarchy has two or more AUTOLOAD( ) definitions...


Nunja, dass innerhalb eines Scopes eine Methode/Funktion nur einmal definiert sein darf, hat sich doch hoffentlich auch schon herumgesprochen, das gilt selbstverständlich auch für eine sub AUTOLOAD{}. Es sei denn, diesbezügliche Warnungen werden mit

Code (perl): (dl )
no warnings 'redefine';


geflissentlich außer Gefecht gesetzt. Wer sowas macht, sollte sich besser dem Kartenspielen (optional mit Schnaps und Bier) widmen :)

Quote
The AutoLoader module works with the AutoSplit module and the "__END__"
token to defer the loading of some subroutines ...


D.h.: Wer lediglich eine eigene sub AUTOLOAD{} definieren möchte, kann auf use AutoLoader; komplett verzichten, damit entfällt auch die Pflege der Datei autosplit.ix mit den Forward-Deklarationen der *.al-Methoden als Stub notiert. Wichtig ist weiterhin, dass es eine sub DESTROY{} geben muss, in dem Moment, wenn eine eigene sub AUTOLOAD{} definiert wurde. Mit der Festlegung eines eigenen, auf @INC aufgesetzten Suchpfades ist es dann recht einfach, seine Klasse um beliebig viele Methoden zu erweitern, Dateiname == Funktionsname, und ob die Datei .al oder .pm oder .pl heißt, ist nur eine Frage der Festlegung.

Gerne ein Beispiel:
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
sub AUTOLOAD{
    my $self = shift;
    # Name der Methode ermitteln
    my $mname = do{
        our $AUTOLOAD =~ /(\w+)$/;
        $1;
    };
    require "auto/$mname.pm";     # wirft Exception, wenn es die Datei nicht gibt
    my $code = $self->can($mname) || die "Die Methode '$mname' ist nicht definiert in Modul 'auto/$mname.pm'";
    $self->$code(@_);
}

sub DESTROY{}


Und siehe da: UNIVERSAL::can(), yes, we can ;)

Einfacher gehts nicht, evntl. noch einen Tipp: Setze den Code der main in einen try-Block und fange Exceptions so auf, dass bereits beim Entwickeln verständliche Fehlermeldungen zu sehen sind (siehe mein Beispiel Dump & die). Erhebe Warnungen in den Status einer Exception anstatt sie auszuschalten.

View full thread AUTOLOAD ist übler Hack