2012-03-26 6 views
2

Angenommen, ich eine Funktion haben, die einen Verschluss zurück:Destructors ohne Klassen

sub generator 
{ 

    my $resource = get_resource(); 
    my $do_thing = sub 
    { 
    $resource->do_something(); 
    } 

    return $do_thing; 
} 

# new lexical scope 
{ 
    my $make_something_happen = generator(); 

    &$make_something_happen(); 
} 

Ich mag wäre in der Lage sein, um zu gewährleisten, wenn $make_something_happe n von Rahmen entfernt wird, kann ich einige $resource->cleanup();

nennen

Natürlich, wenn ich eine Klasse hätte, könnte ich dies mit einem Destruktor tun, aber das scheint ein bisschen Schwergewicht für das, was ich tun möchte. Dies ist nicht wirklich ein "Objekt" in dem Sinne, dass ein Objekt modelliert wird, es ist nur eine Funktionssache, die einen Code beim Start und unmittelbar vor dem Tod ausführen muss.

Wie würde ich das in Perl machen (und, aus Neugier, unterstützt jede Sprache diese Idee)?

+0

Ja, einige andere Sprachen unterstützen dies (obwohl ich keine andere Hand nennen kann als einige Common Lisp-Implementierungen wie SBCL); Es wird normalerweise Finalizer genannt, im Gegensatz zu Destruktor (der Name "Destruktor" deutet auf explizite Speicherfreigabe hin). Eine Systemfunktion nimmt das zu beobachtende Objekt (äh, * Wert *) und die Funktion, die aufgerufen wird, wenn sie tot ist. –

Antwort

4

Ich würde nur eine Klasse dafür verwenden. Segne die Subroutinenreferenz und benutze sie immer noch wie du bist. Die get_resource verwendet dann diese Klasse. Da ich nicht weiß, wie das aussieht, werde ich es Ihnen überlassen, um es zu integrieren:

package Gozer { 
     sub new { 
     my($class, $subref); 
     bless $subref, $class; 
     } 

     sub DESTROY { 
     ...; #cleanup 
     } 
     } 

Wenn alles haben kann es eigene Bereinigungs ich die Klasse Gruppe zwei Code Refs verwenden würde :

package Gozer { 
     sub new { 
     my($class, $subref, $cleanup); 
     bless { run => $subref, cleanup => $cleanup }, $class; 
     } 

     sub DESTROY { 
     $_[0]{cleanup}(); 
     } 
     } 

In Perl glaube ich nicht, dass das Schwergewicht ist. Das Objektsystem fügt einfach Etiketten an Referenzen an. Nicht jedes Objekt muss etwas modellieren, also ist das eine perfekte Art von Objekt.

Es wäre schön, eine Art Finalizer für gewöhnliche Variablen zu haben, aber ich denke, diese würden topologisch die gleiche Sache sein. Sie könnten es mit Perl als tie tun, aber das ist nur ein Objekt wieder.

0

Ich glaube, ich verstehe Ihre Frage. In meinem Fall möchte ich:
* Eine globale Variable, die an einem beliebigen Punkt während der Laufzeit des Skripts gesetzt werden kann
* Um bis zum Ende der Lebensdauer des Skripts dauern
* Explizit reinigen Sie es.

Es sieht so aus, als könnte ich dies tun, indem ich einen END-Block definiere; Es wird "so spät wie möglich" laufen. Sie sollten in der Lage sein, Ihre $ resource-> cleanup(); da drinnen.

Mehr hier: http://perldoc.perl.org/perlmod.html#BEGIN%2c-UNITCHECK%2c-CHECK%2c-INIT-and-END

Das begincheck Programm auf dieser Seite den Code.

Verwandte Themen