in reply to Re: explicitly calling destructor
in thread explicitly calling destructor

Why? Why is it better to have a clean_up() method that DESTROY() calls instead of just a DESTROY() method?

It seems like it potentially makes things more fragile, since it implies that clean_up() can occur independently of destruction, which is not the case. That's precisely the concern -- I don't want to release the resource while there are still active objects.

Yes, I could add a flag to disable the object after clean_up, and modify all methods to inspect it, but that doesn't require a separate clean_up() method, so what does it actually accomplish?

Replies are listed 'Best First'.
Re: Re: Re: explicitly calling destructor
by hossman (Prior) on May 16, 2003 at 06:50 UTC
    Why is it better to have a clean_up() method that DESTROY() calls instead of just a DESTROY() method?
    You pretty much answered that question in your orriginal post...
    I could call the DESTROY method explicity, which would release the lock. But then, I want to make certain that DESTROY is not called again, implicitly, if/when the object is really reclaimed, since the lock will have already been released, making it unsafe.

    DESTROY is "magic", it's whole purpose for existing is to be implicitly called ... eventually. But you never know when, or in what order it will be called on for multiple objects -- And quite frankly, you never know what else perl might want to do it's calling your DESTROY method.

    The simple fact that you think you need to explicitly call DESTROY at a specific time is a strong indication to me that you should rename that method. That's not what DESTROY is for.

      But having a separate clean_up() method would work exactly the same way. Calling it would release the lock. But then, I'd want to make certain it wasn't called again (from DESTROY), if/when the object is really reclaimed, since the lock would have already been released, making it unsafe.

      So I'd still need to either add a pre-destruct flag and check it in every method, as suggested, or use my hack of reblessing to a null class.

      In the general case, I agree with you, of course. If you want to provide a clean-up method through your interface, then certainly don't call it DESTROY. But in this specific case, I'm really trying to fake destruction for an interface that relies on normal destruction, but which is currently borken due to my dangling references. And so in this case, I still don't see the win.

      I understand the magic and am bending it to my will :-)

        So I'd still need to either add a pre-destruct flag and check it in every method, as suggested, or use my hack of reblessing to a null class.

        I think you may have missed the point of diotalevi's code. The DESTROY method checks the pre-destruct flag itself, and bails if it's been set, so there's no need for you to check the flag in every method.

        cheers,

        J

        mla,
        please forgive my naive example but, i think iburrell and hossman are referring to something like below, where the actual lock is your pre-desctruct flag...

        sub clean_up { my $self = shift; if ( $self->{Lock} ) { # # the code to release the lock # $self->{Lock} = 0; } } sub DESTROY { my $self = shift; $self->clean_up(); }