Thread AUTOLOAD ist übler Hack
(13 answers)
Opened by Muffi at 2015-01-13 10:43
Hi lieber Kollege,
dann lass uns das mal zusammen durchnehmen. Vorab: UNIVERSAL::can wird NICHT verbogen, alles bleibt wie's ist. Mal angenommen, die sub AUTOLOAD{} definieren wir in der main und rufen einfach eine Funktion auf: Code (perl): (dl
)
main->configini($path_ini_file); # 'main' als Ersatz für eine Instanz Der Interpreter sucht die sub AUTOLOAD{}, weil configini() nirgendwo zu finden ist. Innerhalb der sub AUTOLOAD{} befragen wir eine Variable our $AUTOLOAD, im Beispiel steht da drin: main::configini. Und interessiert nur der das Word ganz hinten und das findet die RE (\w+)$. Vereinbarungsgemäß liegen die Dateien in @INC/auto als 'name.pm', fürs Beispiel muss es da eine configini.pm geben und die wird mit require eingebunden. Nun die Datei, da steht drin: Code (perl): (dl
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # File auto/configini.pm # keine package-Deklaration, es greift der default: package main; use strict; use warnings; use Config::Tiny; my $CFT = Config::Tiny->new; # gilt nur dateiweit # hier die Definition der Funktion sub configini{ my $self = shift; my $file = shift; return $CFT = Config::Tiny->read($file) || do{ $@ = "Error with CFG-File '$file': $Config::Tiny::errstr"; undef; }; } 1; Nun, require kompiliert die Datei und configini() liegt dann in der Symboltabelle. D.h., bei weiteren Aufrufen configini() greift die sub AUTOLOAD{} gar nicht mehr, sie greift also nur einmal. Da configini() in der Symboltabelle liegt, liefert UNIVERSAL::can() eine Referenz auf den CODE, der sodann über die Instanz aufgerufen werden kann mit allen Argumenten in @_. Vererbung: Eine sub AUTOLOAD{} wird vererbt wie jede andere Funktion. Wenn die Subklasse von der main erbt, können Autoload-Methoden sowohl mit als auch ohne echte Klasseninstanz aufgerufen werden. In der Autoload-Methoden-Dateien kann der Name der package != main deklariert sein. Mit der von mir in den Beispielen vorgeschlagenen Fehlerbehandlung ergibt sich ein aufgeräumter Code ;) |