Ich fing an, etwas Seltsames über Scope::Guard
zu bemerken .
$guard
Variable als allerletzte Anweisung in einem Sub definieren, wird die Subroutine des Guard
rief später als ich erwarte. undef $guard
, wird es aufgerufen, wenn die Referenz ausgeht
Umfang wie dokumentiert. Ich frage mich warum. Der Code ist auch hier
zu finden %Vor% Im Code habe ich meine eigene arme Frau % co_de gemacht % ( Scope::Guard
oben)
nur um das Beispiel so einfach wie möglich zu machen. Sie können auch SGuard
verwenden
und bekomme genau dieselben Ergebnisse, die zumindest für mich unerwartet sind.
Ich erwarte, dass das Scope::Guard
in $mySubGuard
zuerst zerstört werden sollte
und das mySub()
in dem Bereich, der $scopeGuard
aufruft, sollte zerstört werden
letzte. Und so ausgegeben wie:
Ich bekomme über die Ausgabe, wenn ich mySub()
line in mySub verwende.
Wenn ich undef $mySubGuard
line in mySub nicht verwende, komme ich unter output:
Es sieht also so aus, als ob undef $mySubGuard
from $mySubGuard
zerstört wurde
nachdem lokale Variablen für den äußeren Bereich zerstört wurden.
Warum unterscheidet sich das Verhalten nur deshalb, weil ich eine Variable, die sich im Begriff befindet, zu verwerfen außer Reichweite? Und warum ist es wichtig, ob etwas getan wird? danach?
Es sieht so aus, als wäre es eine Art Optimierung. Wenn du undef
eine Variable verwendest und sie danach nicht benutzt, wird sie in eine Art Warteschlange gestellt, um Magie oder etwas zu überprüfen. Aber wenn du danach noch etwas machst, tut es das DESTROY genau dann.
Es könnte auch einen Fehler geben, da es sich bei undef
um einen "Rückgabekontext" handelt, es gibt eine Kopie der Variablen, die auf etwas untersucht wird. Und vielleicht behält Perl einen Verweis, den er später aufräumt, und das Ende des aufrufenden Bereichs.
Sie werden auch bemerken, dass jede andere Anweisung nach undef
-ing den Guard zu erwartetem Verhalten führt. Einschließlich der PBP-empfohlen, alle Subs mit return
zu beenden. Einer von Damians expliziten Gründen war, dass unerwartete Nebenwirkungen vermieden werden.
Problem gelöst: So einfach wie undef
-ing einen Wächter, können Sie seinen Handler geradeaus laufen lassen. Wächter nicht als letzte (implizite Rückkehr) Aussage eines Subs. Haben Sie einen Grund, Wachen ausdrücklich zu entheben, zum Beispiel, dass Sie ihren Handler sofort ausführen wollen, um weiter zu bearbeiten.
Es ist verwirrend und unerwartet, aber definitiv nicht etwas, das in fertigem oder standardisiertem Code auftauchen sollte.
Tags und Links perl memory-management