Re: RFC 254 (v1) Class Collections: Provide the ability to overload classes

[email protected] (Michael G Schwern) Mon, 18 Sep 2000 03:27:47 -0400
Newsgroups perl.perl6.language.objects
Message-ID <[email protected]>
On Mon, Sep 18, 2000 at 05:49:28AM -0000, Perl6 RFC Librarian wrote:
> Here's where the problem lies.  Even though we now have a subclass
> of Frog, the Forest class is still referencing the original Frog
> class and not Frog::Japanese.

The DBI has this very problem!  DBI->connect() returns DBI::db
objects, DBI->prepare() returns DBI::st.  If you want to override the
behavior for statement handles and connections, its not enough to just
subclass DBI::st and DBI::db, you must also subclass DBI and override
connect() and prepare() (and hope DBI doesn't use DBI::st or DBI::db
anywhere else.)

DBI->init_rootclass() is a fairly hairy workaround to this problem.
It works like this:

    package Ima::DBI::db;
    @ISA = qw(DBI::db);

    package Ima::DBI::st;
    @ISA = qw(DBI::st);

    package Ima::DBI;

    use base qw(DBI);
    Ima::DBI->init_rootclass;

    # $dbh is an Ima::DBI::db object, $sth is an Ima::DBI::st
    $dbh = Ima::DBI->connect(...);
    $sth = $dbh->prepare(...);

Ima::DBI->init_rootclass() informs the DBI that Ima::DBI is a subclass
and that Ima::DBI::db and Ima::DBI::st objects should be used.  It
does this by just appending '::db' onto the classname, which means the
names of the classes are fixed.  A Bad Thing.

[From DBI->connect()]

    # XXX this is inelegant but practical in the short term, sigh.
    if ($installed_rootclass{$class}) {
        $dbh->{RootClass} = $class;
        bless $dbh => $class.'::db';
        my ($outer, $inner) = DBI::_handles($dbh);
        bless $inner => $class.'::db';
    }

It works, but to quote Tim Bunce there... *sigh*.


So anyhow, yes, this is a big, icky problem.


-- 

Michael G Schwern      http://www.pobox.com/~schwern/      [email protected]
Just Another Stupid Consultant                      Perl6 Kwalitee Ashuranse
<mendel>         ScHWeRnsChweRN    sChWErN   SchweRN  SCHWErNSChwERnsCHwERN  
    sChWErn  ScHWeRn      schweRn           sCHWErN           schWeRn   
scHWeRN     SchWeRN      scHWErn SchwErn       scHWErn       ScHweRN      
sChwern       scHWerN        scHWeRn           scHWerN        ScHwerN      
SChWeRN scHWeRn           SchwERNschwERn        SCHwern  sCHWErN   SCHWErN   
       sChWeRn