http://www.perlmonks.org?node_id=678152

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

Is the object reference passed in when DESTROY is called? IE can I rely on 'my $self = shift;' being valid?

What Im hoping to achieve is to clean up a database handle in the destructor. I have the 'DBH' saved as a member variable and would like to be able to clear it as such.

sub DESTROY { my $self = shift; $self->{ 'dbh' }->disconnect(); }

Is that valid?

Replies are listed 'Best First'.
Re: cleaning up in DESTROY
by liz (Monsignor) on Apr 03, 2008 at 13:35 UTC
    FWIW, I've seen undef being passed as first parameter to DESTROY in earlier 5.8.x versions of Perl when using threads and at global destruction. I would consider that as a bug, but it *does* seem to happen (in fact, some of my Thread:: modules with DESTROY methods explicitely check for that eventuality). Liz
Re: cleaning up in DESTROY
by mr_mischief (Monsignor) on Apr 03, 2008 at 16:19 UTC
    Here's a simple test case. Empirically, if you have this:

    #!/usr/bin/perl -- use strict; use warnings; package Foo; sub new { my $self = { 'foo' => 'bar' }; return bless $self; } sub DESTROY { print $_[0]{'foo'} . "\n"; } package main; my $foo = Foo->new; exit;

    then it produces this:

    bar

    So, as a rule I'd say yes it'll be there.

    However, be sure to consider liz's comments in Re: cleaning up in DESTROY, the thread at Object reference disappearing during global destruction, and phillup's journal entry at http://use.perl.org/~phillup/journal/21827 which covers unordered global destruction as well. That appears to be a dark corner in which quite a few people find themselves. I don't think I'd call it a bug, per se, but maybe perlobj could be a little more verbose on the implications of what happens during global destruction.

Re: cleaning up in DESTROY
by samtregar (Abbot) on Apr 03, 2008 at 17:27 UTC
    As a side note, you don't have to do that with DBI. It will disconnect automatically when the last reference to the handle goes out of scope. So as long as you're not leaking handles somewhere you don't need to worry about calling disconnect() explicitly.

    -sam

Re: cleaning up in DESTROY
by Fletch (Bishop) on Apr 03, 2008 at 13:30 UTC

    Wouldn't be very much of a DESTROY method if the instance weren't passed in as a parameter, now would it?

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

      i think your should call the $dbh->disconnect with a independent method in the package definition. for example:
      sub finish { my $self = shift; $self->{'dbh'}->disconnect; }