Subject: | meta_info entries shared among classes |
If you declare relationships in your base class and then again in a data class, the __meta_info hash will end up containing hash references that are shared among classes. This severely buggers up relationship definitions, of course.
It's because this (in Class::DBI::_extend_meta):
my %hash = %{ $class->__meta_info || {} };
$hash{$type}->{$subtype} = $val;
$class->__meta_info(\%hash);
dereferences the main metadata hash, but it doesn't dereference $hash{$type}. If there's already a hashref there - because we're inheriting from a class that defined a relationship of that type - then it will be shared.
In short, if you define a has_a relationship in your base class then all the has_a relationships of all your classes will be assigned to all your classes. this isn't such an odd thing to do, either. i triggered the bug with this:
__PACKAGE__->columns(DATE => qw( date cdate ));
__PACKAGE__->has_a( date => 'Delivery::Machinery::Date' );
__PACKAGE__->has_a( cdate => 'Delivery::Machinery::Date' );
which is true of all the classes in this particular application.
The fix is easy, if a little bodgy. Just add an extra dereference to Class::DBI::_extend_meta:
sub _extend_meta {
my ($class, $type, $subtype, $val) = @_;
my %hash = %{ $class->__meta_info || {} };
my %subhash = %{ $hash{$type} || {} };
$subhash{$subtype} = $val;
$hash{$type} = \%subhash;
$class->__meta_info(\%hash);
}
best
will