Re: relationship namespace
[prev]
[thread]
[next]
[Date index for 2004/12/20]
On 20 Dec 2004, at 12:01, Tony Bowden wrote:
> On Mon, Dec 20, 2004 at 11:42:45AM +0000, William Ross wrote:
>> Picking through the metadata reveals that all my classes have the same
>> has_a set, ie that the metadata hash is shared among all cdbi
>> subclasses rather then existing separately in each.
>
> If that's really true it's quite a serious bug.
Found it. I'm not exactly sure it's a bug, as it only comes up if you
declare relationships (or anything else that touches on class data) at
more than one level in the inheritance tree, and there's nothing to say
you're allowed to do that. You might just want to prohibit it :)
The problem is in Class::DBI::_extend_meta. This:
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 (and only if) we are inheriting from a class that has
already been assigned an attribute of this type, then $hash{$type} will
contain a hashref and will subsequently be shared between the
superclass and all its subclasses even though the hash that contains it
is different each time.
It might be a good idea to build some configurable safeguards into
Class::Data::Inheritable, but it's far too pretty in there for such
grubby practicalities. Instead, how about:
--- /Users/will/Desktop/DBI.pm.orig Mon Dec 20 21:43:08 2004
+++ /Library/Perl/5.8.5/Class/DBI.pm Mon Dec 20 21:43:25 2004
@@ -1022,7 +1022,9 @@
sub _extend_meta {
my ($class, $type, $subtype, $val) = @_;
my %hash = %{ $class->__meta_info || {} };
- $hash{$type}->{$subtype} = $val;
+ my %subhash = %{ $hash{$type} || {} };
+ $subhash{$subtype} = $val;
+ $hash{$type} = \%subhash;
$class->__meta_info(\%hash);
}
Let me know if you think this needs a test.
best
will