DESTROY hat eine unerwartete Sequenz aufgerufen

8

Ich fing an, etwas Seltsames über Scope::Guard zu bemerken .

  • Wenn ich eine $guard Variable als allerletzte Anweisung in einem Sub definieren, wird die Subroutine des Guard rief später als ich erwarte.
  • Wenn ich es nicht ignoriere oder wenn ich etwas tue (alles) nach 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:

%Vor%

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:

%Vor%

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?

    
Peter V. Mørch 11.07.2012, 07:04
quelle

1 Antwort

1

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.

    
Axeman 11.07.2012 13:20
quelle

Tags und Links