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

Hi! I have a bit of a complex problem. Sorry if this is to much for discussion here, but hey, I bow humbly at the gates waiting for a miracle! My home-grown framework here includes OO Inheartance, Singletons, and Object Encapsulation. Basically, I have a "Table" class that abstracts db table functionality. I derive specific classes from Table, for example Club and Player. Club and Player are singletons. As part of the constructor for Player and Club they call methods in Table class that define Columns, Indexes, Foreign Keys etc. There are helper objects to Table that represent Foreign Keys, Indexes and so forth. Now for the interesting problem. I'll put code snipets below. When a data object (Let's Say "Affiliation" calls the Table method "addFks" to add a foreign key to the Tables FKS array, the Foreign Key object is successfully created. The reference to the FK is successfully pushed onto the Table FKS array. But upon return to the Affiliation constructor, the FK reference is screwed up. I have nearly identical processing for the IDX array and it works just fine. I'm using Eclipse/EPIC as a development platform, and in the debugger the object reference in the FKS array still shows that it is a FK object, but you can't expand the hash to see the contents. Ok, here are the code snippets

"Affiliatoin" data class

#============================================================== # FILE: Affiliation.pm # # DESCRIPTION: Class that represents the affiliation # a player with a club # #============================================================= package DataObjects::Affiliation; require MySqlTools::Table; our @ISA = qw(MySqlTools::Table); require DataObjects::Club; require DataObjects::Player; require DataObjects::ClubDGAW; use Log::Log4perl qw(get_logger :levels); use strict; use warnings; my $affObject; #============================================================ # # METHOD: new # #=========================================================== sub new { my $class = shift; if ($affObject) {return affObject;} #-- Singleton . . $self->addColumn({name=>'playerID',..... . . #---------------------------------------------------- # Define foreign keys and indexes #---------------------------------------------------- $self->{FKPLAY} = $self->addFks({ NAME =>'Aff_Player_FK', OWNCOLS =>['playerID'], REFTABLE =>'player', REFCOLS =>['playerID'], ONDELETE =>'CASCADE', }); ===> #################################################### ###### - HERE $self->{FKPLAY} contains a valid FK ###### reference, $self->{FKS}[0] contains a ###### funky reference, the debugger shows it ###### to be a FK object, but the hash is ###### empty! ###################################################

snippet from the "Table" class

#================================================== # # FILE: Table.pm # # DESCRIPTION: Abstract class to define a table # #================================================= package MySqlTools::Table; require MySqlTools::Column; require MySqlTools::ForeignKey; require MySqlTools::Index; require MySqlTools::ResultSet; require MySqlTools::Database; require Utilities::Properties; use Log::Log4perl qw(get_logger :levels); use strict; use warnings; #================================================== # # METHOD: new # #================================================ sub new { my $class = shift; my $parm = shift; . . bless( $self, $class ); return $self; } . . #=================================================== # # METHOD: addFk # #================================================== sub addFks{ my $self = shift; my $parms = shift; my $log = get_logger("MySqlTools::Table"); my $fkName = $parms->{NAME}; $parms->{OWNTABLE} = $self->{NAME}; $parms->{DBH} = $self->{DBH}; my $fk = MySqlTools::ForeignKey->new($parms); if ( !$fk ) { $log->error('FK->new failed!'); } else { ---> push @{$self->{FKS}}, $fk; } ***> return $fk; }
As I stated earlier, I have very similar methods/helpers for working with Indexes, and their is not a problem there. I've reviewed the code side by side, and I'm stumped.

Clarifications & Solution

It looks like this was more of a debugger bug than a problem in the code. The attribute $self->{FKS} is an array reference, so the cast of the reference to a real arry @{$arrayRef} is done so that push will work. When the "Table::AddFks" method is called, a valid FK Ref was pushed onto $self->FKS (see ---> in the code above). When a breakpoint in the dugger is set to ***> both $fk, and $self->{FKS}[0] hold a valid reference to an FK object. You can expand and explore the FK object hash. When the code continues to ===> the debugger shows that $self->{FKS}[0] holds a reference to a FK object, however the object can not be "expanded and explored". At this same break-point the $self->{FKPLAY} attribute holds a valid, explorable FK reference. After further testing, later on in the code when I iterate through the array, everything works as expected, and the variable explorer shows the FKS array to contain valid, explorable FK objects. It appears that I was lead down a rabbit hole by a bug in the debugger :) Thank you for a quick response, and I hope this node is able to help others that may be using the Epic deubgger. (I'm still a newbe here at the Monastery!)

More Clarifications

I have been requested to show the MySqlTools::ForeignKey->new method, just to make this post complete, here she is.....

sub new { my $class = shift; my $parm = shift; my $log = get_logger("MySqlTools::ForeignKey"); my $self = {}; $self->{DBH} = MySqlTools::Database->new(); $self->{NAME} = $parm->{NAME}; . . $log->info('New ForeignKey object initilized'); bless( $self, $class ); return $self; }

Thanks

Replies are listed 'Best First'.
Re: Object Reference ^%#)#&* dissapers
by shmem (Chancellor) on Aug 28, 2008 at 21:50 UTC
    At the line
    my $fk = MySqlTools::ForeignKey->new($parms);

    the $fk might well resolve to a true value; but is it what you expect? Try dumping the thingy at that point with e.g. Data::Dumper. But I suspect the culprit being in MySqlTools::ForeignKey which you didn't post. Adding debug logging to that one might give some clue.

    update:

    As I stated earlier, I have very similar methods/helpers for working with Indexes, and their is not a problem there. I've reviewed the code side by side, and I'm stumped.

    More often than not that doesn't help, since one is blind to one's own bugs. I suspect some leftovers being in the way, of the sort of your addFks method, which stuffs $fk into an object field and returns $fk. Try logging the return value(s) of your methods.

Re: Objet Reference ^%#)#&* dissapers
by ikegami (Patriarch) on Aug 28, 2008 at 20:53 UTC

    You don't show where
    $self->{FKS}[0]
    is set so much as
    $self->{FKS}[-1]
    (assuming FK->new failed! isn't in the log file)

    What's scalar(@{ $self->{FKS} }) at "HERE"?