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]

Reply via email to