[Melbourne-pm] Subclassing DBI

Mathew Robertson mathew.robertson at netratings.com.au
Sun Feb 12 14:37:44 PST 2006

Which is great and all -> ther are specific cases where sub-classing DBI 
is the right thing to do.'

However, in this case it appears (from the limited code snippet) that 
your class has "using" relationship to DBI, and doesn't have an "isa" 
relationship.   ie:  in it simplest terms, "isa" means that you should 
publicly sub-class, where as "using" means that you should implement as 
a wrpper class.

Do you really need to sub-class?

Jacinta Richardson wrote:

>>When I run the driver that uses TestLib::DBConn I get an error:
>>DBI subclasses 'TestLib::DBConn::db' and ::st are not setup, RootClass
>>ignored at ./test.pl line 98
>>Any ideas as to how I could fix this?
>The relevant code you're hitting is as follows:
># handle basic RootClass subclassing:
>my $rebless_class = $attr->{RootClass} || ($class ne 'DBI' ? $class : '');
>if ($rebless_class) {
>    no strict 'refs';
>    if ($attr->{RootClass}) {	# explicit attribute (rather than static call)
>	delete $attr->{RootClass};
>	DBI::_load_class($rebless_class, 0);
>    }
>    unless (@{"$rebless_class\::db::ISA"} && @{"$rebless_class\::st::ISA"}) {
>	Carp::carp("DBI subclasses '$rebless_class\::db' and ::st are not setup,
>RootClass ignored");
>	$rebless_class = undef;
>	$class = 'DBI';
>    }
>    else {
>	$dbh->{RootClass} = $rebless_class; # $dbh->STORE called via plain DBI::db
>	DBI::_set_isa([$rebless_class], 'DBI');     # sets up both '::db' and '::st'
>	DBI::_rebless($dbh, $rebless_class);        # appends '::db'
>    }
>sorry about the wrapping.  This means that DBI doesn't think that you've
>subclassed it correctly.
>Further, from the documentation at:
>http://cpan.uwinnipeg.ca/htdocs/DBI/DBI.pm.html (Subclassing the DBI)
>DBI can be subclassed and extended just like any other object oriented module.
>Before we talk about how to do that, it's important to be clear about how the
>DBI classes and how they work together.
>By default $dbh = DBI->connect(...) returns a $dbh blessed into the DBI::db
>class. And the $dbh->prepare method returns an $sth blessed into the DBI::st
>class (actually it simply changes the last four characters of the calling handle
>class to be ::st).
>The leading 'DBI' is known as the 'root class' and the extra '::db' or '::st'
>are the 'handle type suffixes'. If you want to subclass the DBI you'll need to
>put your overriding methods into the appropriate classes. For example, if you
>want to use a root class of MySubDBI and override the do(), prepare() and
>execute() methods, then your do() and prepare() methods should be in the
>MySubDBI::db class and the execute() method should be in the MySubDBI::st class.
>So, your changes to connect should be in TestLib::DBConn::db.  If you don't want
>to make any changes to DBI::st, just subclass it to get the name right.
>If you have any other questions that aren't answered by that documentation, feel
>free to ask!
>	J
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.pm.org/pipermail/melbourne-pm/attachments/20060212/304c9ca5/attachment.html

More information about the Melbourne-pm mailing list