Thread unuse module;: any workaround (19 answers)
Opened by lichtkind at 2005-10-17 23:23

ptk
 2005-10-24 00:33
#58976 #58976
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
[quote=murphy,23.10.2005, 16:10][quote=Cremator,18.10.2005, 21:01][...]
Erst "säubern" und dann den Modulnamen aus dem INC-Hash löschen. So kannst Du sicher sein, das keine Reste von der zuvor geladenen Version übrig sind, da der Namespace dann auch leer ist.
[...][/quote]
Aber Vorsicht: Das herumspielen am Namensraum kann mit unerwünschten Nebenwirkungen verbunden sein!

Perl führt nicht für jeden Subroutinenaufruf eine volle Suche im Namensraum aus, sondern hat da irgendeinen schlauen Puffermechanismus. Wenn man also ein Modul auf die besagte Art und Weise "entlädt", dann kann es passieren, dass Code, der das Modul benutzt, und bereits mindestens einmal ausgeführt wurde, nicht mehr funktioniert, selbst wenn man das entladene Modul erneut lädt.[/quote]
Bei normalen Subroutinen ist mir kein "Puffermechanismus" bekannt. Der folgende Code funktioniert wie erwartet:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
sub test {
warn "Alter Test!";
}
test();
eval q{
sub test {
warn "Neuer Test!";
}
};
test();
Die auftretende Warnung kann man ausschalten (no warnings "redefine", wenn ich mich nicht irre).

Probleme kann es geben, wenn man Module wie "autouse" verwendet. Auch kann ich mir gut vorstellen, dass der AutoLoader mit nachladen nicht gut zurechtkommt. Und überall dort, wo mit Funktionsreferenzen gearbeitet wird, muss man vorsichtig sein. In Tk-Code schreibt man z.B. oft:
Code: (dl )
$mw->Button(-command => \&machwas)->pack;

Wenn jetzt machwas() umdefiniert wird, dann zeigt die Referenz noch immer auf die alte Funktion. Um dieses Problem zu umgehen, kann man stattdessen schreiben:
Code: (dl )
$mw->Button(-command => sub { machwas() })->pack;

Was zwar ein paar Mikrosekunden langsamer ist, aber das fällt bei einem Klick nicht auf.

"perldoc perlobj" sagt übrigens zum Methodencache:
Code: (dl )
1
2
3
If a missing method is found in a base class, it is cached in the cur-
rent class for efficiency. Changing @ISA or defining new subroutines
invalidates the cache and causes Perl to do the lookup again.

Also auch hier kein Problem.

View full thread unuse module;: any workaround