I don't know where to start with this. When I have a problem this weird
wisdom has shown I'm doing something stupid. So, I'm looking for a sanity
check and mostly a break from staring at the code, and a gin and tonic
wouldn't hurt either.
Anyway, I thought I'd share this just in the remote chance someone has an
idea.
I have a very simple Moose class I use with my unit tests. Its job is to
populate a database with data needed for running a test and then clean up
when done. I'm using DBIx::Class, BTW.
The database is hierarchal with an "institution" table at the top -- all
other tables join up to institution. There's cascade deletes in the
Postgresql database so to clean up all I have to do is delete the
institution row this module created. So, I added a DEMOLISH:
sub DEMOLISH {
my $self = shift;
my $institution = $self->institution;
$institution->delete;
}
And indeed, that worked perfectly.
Here's the first hint of weirdness: I initially wrote that like this:
sub DEMOLISH {
my $self = shift;
$self->institution->delete;
}
But that didn't delete the row. It just silently did nothing! Nothing
showed with DBIC trace or with DBI->trace(1). And no error. But written
the first way worked. No kidding.
So, today I modified a test by reorganizing some subroutine -- should not
have made any difference in execution. But the same problem came back.
So, here's the code -- with my frantic debugging statements in the Moose
class:
package My::TestAccount;
use Moose;
use namespace::autoclean;
use Data::Dumper;
$Data::Dumper::Maxdepth = 4;
use My::DB;
has [ qw/
schema
institution
/ ] => ( is => 'ro', lazy_build => 1 );
sub _build_schema {
return My::DB->connect({ dsn => 'dbi:Pg:dbname=test' });
}
sub _build_institution {
my $self = shift;
$self->debug;
warn "building institution\n";
my $schema = $self->schema;
return $schema->resultset( 'Institution' )->create( {
name => 'Institution',
type => 2,
} );
}
sub DEMOLISH {
my $self = shift;
warn "********* In DEMOLISH $self **********\n";
my $institution = $self->institution;
my $x = ref $institution;
warn "after 1 [$institution] [$x]\n";
$institution->delete;
warn "after delete\n";
}
Now here's my test script:
#!/usr/bin/perl
use strict;
use warnings;
use FindBin qw/$Bin/;
use lib "$Bin/../lib"; # t directory lib
use My::TestAccount;
my $act = My::TestAccount->new;
warn "\n[ **** $act ***]\n";
my $i = $act->institution;
warn "institution = $i\n";
exit;
Now running I get:
[ **** My::TestAccount=HASH(0x841d1f0) ***]
building institution
INSERT INTO institution ( name, type) VALUES ( ?, ? ): 'Institution', '2'
institution = 244 (I serialize objects to their id)
********* In DEMOLISH My::TestAccount=HASH(0x841d1f0) **********
before call to institution
Use of uninitialized value $institution in concatenation (.) or string at
lib/My/TestAccount.pm line 66 during global destruction.
after 1 [] []
Eh, where did $self->institution go?
And more crazy stuff: If I modify my test script and add just __END__ after
that exit like this:
#!/usr/bin/perl
use strict;
use warnings;
use FindBin qw/$Bin/;
use lib "$Bin/../lib"; # t directory lib
use My::TestAccount;
my $act = My::TestAccount->new;
warn "\n[ **** $act ***]\n";
my $i = $act->institution;
warn "institution = $i\n";
exit;
__END__
Then running I now get what I expect:
[ **** My::TestAccount=HASH(0x86841f0) ***]
building institution
INSERT INTO institution ( name, type) VALUES ( ?, ? ): 'Institution', '2'
instution = 251
********* In DEMOLISH My::TestAccount=HASH(0x86841f0) **********
before call to institution
after 1 [251] [My::DB::Result::Institution]
*** delete in DBIx::Class::Row
DELETE FROM institution WHERE ( id = ? ): '251'
after delete
Ain't that crazy?
Ok, there's nothing for anyone to go on there. But, anyone have a guess?
I'm running 1.08 Moose ( & DBIC 0.08122). My only guess is perl 5.10.0 on
this machine.
Perhaps I'm confused how DEMOLISH works?
--
Bill Moseley
[email protected]