Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Writing a REAL destructor

by NaSe77 (Monk)
on Jun 05, 2002 at 07:53 UTC ( [id://171751]=perlquestion: print w/replies, xml ) Need Help??

NaSe77 has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks

how do i write a real Dectructor that destroyes the intance and makes the garbage collection when called and not when perl thinks the variable isn't needed anymore.
for intance sticking to the example used in perltoot if i call the methode DESTROY : the methode will be executed but also when the program ends ...
package Person; use strict; use warnings; use diagnostics; my $Census = 0; sub new{ my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; $self->{NAME} = undef; # "private" data $self->{"_CENSUS"} = \$Census; bless ($self, $class); ++ ${ $self->{"_CENSUS"} }; return $self; } sub name { my $self = shift; if (@_) { $self->{NAME} = shift } return $self->{NAME}; } 1; # so the require or use succeeds sub DESTROY { my $self = shift; print $self->{NAME}." dies now: life was nice\n"; -- ${ $self->{"_CENSUS"} }; }
#! /usr/bin/perl -w use strict; use warnings; use diagnostics; use Person; my $me = new Person; $me->name("Andy"); $me->DESTROY;
gets me the following output :
Andy dies now: life was nice Andy dies now: life was nice

----
NaSe
:x

Replies are listed 'Best First'.
(MeowChow) Re: Writing a REAL destructor
by MeowChow (Vicar) on Jun 05, 2002 at 07:59 UTC
    The DESTROY method is special because perl calls it when it realizes it can garbage-collect the object in question. If you would like to manually release the object from memory (by the way, do you have a good reason for this?), you should not call DESTOY directly, which, as you noted, will simply cause it to be called twice. Instead, you delete the last reference to the object, eg:
    my $me = new Person; $me->name("Andy"); undef $me;
    Immediately after the undef(), the object will be freed (because Perl uses a ref-counting GC) and DESTROY called.

    ps. My condolences regarding Andy.

       MeowChow                                   
                   s aamecha.s a..a\u$&owag.print
      A purely theoretical follow up question (just because I am curious):

      When you undef an object, is it really freed immideately, or just marked up for collecting, while the GC decides when to really take care of it all by itself? Reason I ask is that I seem to recall that you can not trust this to happen at any given point no matter what you do - but the odds are better if you undef.

      Note that if you need that finegrained control over your memory and/or objects, if this really matters, then you probably have lots of other, more important problems, such as choice of language, hardware or the problem/project itself. :) So I am just asking technically, what really happens?


      You have moved into a dark place.
      It is pitch black. You are likely to be eaten by a grue.
        I believe undefing a reference was given extra magic to act as a forceful and immediate call to action for the garbage collector. I may be wrong and objects may always be immediately collected as soon as the ref counter hits bottom though.

        Makeshifts last the longest.

        A purely theoretical follow up answer (because I know very little about perl internals):

        I believe it's freed immediately. The issue you're probably recalling is that there's no orderly destruction of objects when a program is terminating.

           MeowChow                                   
                       s aamecha.s a..a\u$&owag.print
      i see thanks i knew tat perl uses ref-counting but now its more clear and i think i can use that ...
      i wanted to have some kind of counter which says how many instances of my class there are (therefor the variable $Census) and since some of my intances will die during my programm i thought to do it this way would be a good idea

      i still wonder if there is a way to do this some kind in sub DESTROY though

      thanks for the condulence andy was really a good guy ...

      ----
      NaSe
      :x

        Keeping track of the number of instances can very well be done via DESTROY. I wouldn't put in a reference in the object though. Then you make the count accessable outside your class, and you probably don't want to do that.

        Use something like:

        package MyClass; my $count = 0; sub new { my $proto = shift; my $class = ref $proto || $proto; $count ++; my $obj = ....; bless $obj => $class; } sub DESTROY { $count --; }
        And do not call DESTROY yourself. Perl will do that for you.

        Abigail

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://171751]
Approved by MeowChow
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2024-04-20 16:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found