[Catalyst] Catalyst::Model::CDBI::Sweet, Class::DBI::Loader and inheritance

Will Hawes info at whawes.co.uk
Wed May 4 17:42:15 CEST 2005


I want to use the improved search() method in Catalyst::Model::CDBI::Sweet as the default for my model classes (e.g. Hops::M::CDBI::Beer in the Hops application). This can be made to work if package, use and require statements for each model class are hardcoded (as in "Synopsis" in the POD for Sweet). Under these circumstances the desired functionality can be achieved by dropping in "use Catalyst::Model::CDBI::Sweet" in place of "use Class::DBI". But I do not want to hard code this sort of stuff.

Using Class::DBI::Loader introduces a problem. Class::DBI::Loader makes all generated classes inherit from Class::DBI::mysql (or Class::DBI::SQLite, etc, depending on your rdbms). You can still inherit from Sweet explicitly:

Class::DBI::Loader->new(
    additional_base_classes => qw/Catalyst::Model::CDBI::Sweet/,
    ...
);

But additional_base_classes adds to the end of @ISA. Since perl reads @ISA from left to right, in this case the inheritance order is

1) Class::DBI::mysql
2) Catalyst::Model::CDBI::Sweet

Calling $generated_class->search() will therefore still call Class::DBI->search() rather than Catalyst::Model::CDBI::Sweet->search().

The ideal solution would be to integrate the great stuff in Catalyst::Model::CDBI::Sweet into Class::DBI, but Class::DBI's author seems not to agree on at least one of the ideas (see the recent thread on the CDBI mailing list "search() without search criteria"), so the alternative is to change the inheritance order.

I have tested this by hacking Class::DBI::Loader->_load_classes() to generate something along the lines of:

use base qw[Catalyst::Model::CDBI::Sweet Class::DBI::mysql ...];

Now <generated_class>->search() calls Catalyst::Model::CDBI::Sweet::search() rather than Class::DBI::search(). I have not seen any adverse side effects yet.

It might be useful if Class::DBI::Loader allowed classes to be added to the start of @{ $generated_class }::ISA as well as the end, to allow full control of the inheritance order. Maybe something along the lines of

Class::DBI::Loader->new(
    base_classes => [Catalyst::Model::CDBI::Sweet], # <- added to @ISA before Class::DBI::mysql and additional_base_classes
    ...
);

Comments appreciated.

Regards

WH




More information about the Catalyst mailing list