2012-05-27 6 views
14

Diciamo che ho una classe Perl che ha un metodo DESTROY. Questo metodo viene utilizzato per rilasciare implicitamente una risorsa esterna, ad esempio un handle di file o una transazione di database.Come si distrugge esplicitamente un oggetto in Perl?

Data un'istanza di questa classe, mi piacerebbe distruggerla esplicitamente. Lo scopo principale di questo è quello di chiamare il metodo DESTROY in modo che la risorsa esterna possa essere rilasciata. Tuttavia, avere l'oggetto stesso rilasciato dalla memoria sarebbe un ulteriore vantaggio.

Come posso fare questo? Ho preso in considerazione la possibilità di chiamare direttamente il metodo DESTROY e di definire le variabili che fanno riferimento all'oggetto.

risposta

17

oggetti Perl5 vengono distrutti non appena l'ultimo riferimento a loro scompare, a meno che non si dispone di strutture auto-referenziale (vedi Destructors e la Due fase di garbage collection paragrafo dopo che per alcune interessanti informazioni).

Se non si hanno riferimenti personali, non è necessario preoccuparsi di nulla, il metodo DESTROY verrà chiamato quando è necessario; provare a distruggere l'oggetto da solo non sarebbe sicuro (come puoi essere sicuro che l'oggetto non sia riferimento da qualche altra parte), a meno che tu non stia facendo riferimento anche a te stesso (se ciò è effettivamente possibile, e ciò duplicherebbe gli sforzi di Perl, che non è una buona idea).

Quindi direi, fino a quando non si dispone di riferimenti ciclici:

  • Se si desidera rilasciare risorse esterne in un punto specifico nel codice, farlo in modo esplicito con un release/close/dispose/qualsiasi metodo (che potrebbe essere chiamato anche il codice DESTROY).
  • Se non ti interessa che quel rilascio avvenga esattamente a quel punto del tuo codice, solo che alla fine viene chiamato, non ti preoccupare.
  • Non preoccuparti per l'oggetto perl stesso.

Se si dispone di riferimenti ciclici, avrete bisogno di essere molto più attenti, e utilizzare riferimenti deboli (vedi Scalar::Util) per rompere i cicli.

(in altre parole, non so di un modo per esplicitamente delete un oggetto perl. Che non funziona bene con un sistema di raccolta dei rifiuti di riferimento contati.)

+0

Sei sicuro che gli oggetti vengono distrutti esattamente dopo che non sono stati referenziati? Conosci qualche fonte autorevole che lo confermi? Pensavo che quel tipo di comportamento non fosse garantito dal garbage collector. – Sam

+1

Il documento che ho citato: "Quando l'ultimo riferimento a un oggetto scompare, l'oggetto viene automaticamente distrutto". Ma come ho detto, rendi esplicito se vuoi rilasciare risorse esterne in un dato momento. Questo è per per5 btw, perl6 potenzialmente ha uno schema di raccolta delle differenze. – Mat

4

È possibile utilizzare undef distruggere esplicitamente un oggetto. Il seguente codice lo illustra.

package MyPackage; 

sub new { 
    print "In new\n"; 
    return bless {}; 
} 

sub DESTROY { 
    print "In DESTROY\n"; 
} 

package main; 

my $Obj = MyPackage->new(); 
<STDIN>; 
undef $Obj; 
<STDIN>; 
+11

'undef' distrugge solo l'oggetto se ciò che si dà è l'ultimo riferimento. Prova ad aggiungere "my $ Cpy = $ Obj;" prima di "undef", non vedrai distruggere chiamato prima della fine del programma. – Mat

Problemi correlati