Skip Menu |

This queue is for tickets about the IMAP-Client CPAN distribution.

Report information
The Basics
Id: 50436
Status: new
Priority: 0/
Queue: IMAP-Client

People
Owner: Nobody in particular
Requestors: cpan [...] grepular.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: DESTROY not called until application exits
Date: Tue, 13 Oct 2009 11:43:35 +0100
To: bug-IMAP-Client [...] rt.cpan.org
From: Mike Cardwell <cpan [...] grepular.com>
The DESTROY method has been implemented incorrectly to the extent that it wont be called until the application ends. When an object goes out of scope the DESTROY method is called on that very object. By storing each object in a package variable on creation you're guaranteeing that it doesn't go out of scope until the application exits gracefully. In the below example, when do_stuff returns I would expect the imap connection to be disconnected automatically without me having to explicitly call the disconnect() function, because the object has gone out of scope: ====================================================================== foreach( @large_number_of_users ){ do_stuff( $_ ); } sub do_stuff { my $imap = new Lboro::IMAP::Client; $imap->connect( PeerAddr => 'localhost', ); $imap->login( $_[0], 'pass', ); ## Do some operations on the imap connection } ====================================================================== It doesn't do that, because a copy of the object still exists in $IMAP::Client::Instances so the DESTROY method isn't called. This can be fixed by removing the Interfaces variable and simplifying DESTROY. Here's a patch against 0.13: ====================================================================== --- Client.pm.original 2009-10-13 11:22:00.000000000 +0100 +++ Client.pm 2009-10-13 11:39:34.000000000 +0100 @@ -30,7 +30,6 @@ %EXPORT_TAGS = (); # Create Class variables -my %Instances; my @SERVER_RESPONSES = ('exists', 'recent'); # constant value my $server_response_callback = undef; my $ID; @@ -744,7 +743,6 @@ 'auth' => '', }, $proto; - $Instances{$self->{'ID'}} = \$self; # If a server was supplied, try to connect to it if (my $server = shift) { if ($self->connect(PeerAddr => $server)) { @@ -760,18 +758,8 @@ } sub DESTROY { # Undocumented: Not to be directly called my $self = shift; - if ($Instances{$self->{'ID'}}) { - $self->disconnect(); # FIXME: Probably not nessesary - delete $Instances{$self->{'ID'}}; - return; - } - - # If we reach here, we didn't find ourself, which is a seirous problem - warn "ERROR: Could not find self in Instances upon DESTROY - Something is seriously wrong!\n"; - foreach my $key (keys %Instances) { - warn "PANIC DUMP: Instance name: ".(($Instances{$key}->{'name'}) ? $Instances{$key}->{'name'} : "(none)")."\n"; - } - die "DUMP COMPLETE: Aborting...\n\n"; + $self->logout(); + $self->disconnect(); } ##### Object manipulation functions ======================================================================