Discovering bugs while going to bed

ethan on 2003-01-26T08:53:16

There is a special sort of design-pattern that I've come up during my attempts with XS that has so far proven its usefulness quite often. Consider the following setup in a C-header:



struct dbx { ... } DBX; struct dbxemail { ... } DBXEMAIL; char * dbx_get_email_body(DBX *dbx, DBXEMAIL* email);



For an object-oriented approach, where a DBX- and a DBXEMAIL object exists, this is sub-optimal, since the DBXEMAIL object needs a reference to a DBX in order to be able to say $dbxemail->get_body.

So in my XS, I wrapped the DBXEMAIL struct thusly:

struct dbx_email { DBX *dbx; DBXEMAIL *email; char *header; /* just the header */ char *body; /* just the body */ } DBX_EMAIL;

Typemaps take care of all the conversions, etc. Very convenient. get_body() then could look like this:

char * get_body(self) DBX_EMAIL *self; CODE: RETVAL = dbx_get_email_body(self->dbx, self->email); OUTPUT: RETVAL

Yet, while going to bed last night I was thinking about this pattern, and more specifically about this piece of code:



my $dbxemail; { my $dbx = Mail::Transport::Dbx->("file.dbx"); $dbxemail->get(0); # first message } print $dbxemail->get_body;


The destructor of Mail::Transport::Dbx objects would get invoked (and thus destroying my DBX* structure) while $dbxemail would still hold a pointer to this (now freed) DBX. First thing I did this morning was trying it and, yes, it indeed dumped core.

The fixes themselves were harmless. DBX_EMAIL->dbx is no longer a DBX* but now a SV* (namely the DBX* as a Perl object) so that I can increase and decrease the refcount where necessary. Of course, I have to do a few things manually that'd normally be taken care of by the typemaps, but that could probably be done by a macro if it gets too annoying.

Anyway, just wanted to inform the world out there that bugs can be discovered (and even fixed) while doing other things (like brushing your teeth, dining with your girl-friend etc.). Don't let your mind rest when you're away from the computer. Programming Perl can be carried out everywhere (even in mind, or possibly in your dreams). I still hope that some day I wake up in the morning, rush to my computer and simply type down the module I programmed during the night while dreaming. Mozart worked a little like that: He wrote down one piece of music composed previously in mind and at the same time his mind was already composing the next symphony. Sigh, I wish I was a genius!