Re: A plan for fixing _fix_metaclass_compatibility
[email protected] (Dave Rolsky)
| Newsgroups | perl.moose |
|---|---|
| Message-ID | <[email protected]> |
On Sun, 7 Sep 2008, Stevan Little wrote:
>> So that's what I'd like to implement. The algorithm goes like this:
>>
>> 1. Look for a common parent class between the two metaclasses (often this
>> will end up being Moose::Meta::Class). If there is none, there's an
>> incompatibility. If there are multiple common parents, give up, because I
>> don't want to deal with multiple inheritance ;)
>>
>> 2. For each class in the chain from a metaclass to the common parent, see
>> if that class is a role-only subclass.
>>
>> 3a. If all of these subclasses are role-only subclasses _in both chains_,
>> we just need to combine all the roles done in both chains, and make a new
>> subclass for said roles.
>>
>> 3b. If any of the classes in the chains are _not_ role-only subclasses, we
>> have a real incompatibility, and die just like we do now.
>>
>> The catch is how to determine if a given metaclass is a role-only subclass,
>> and this is where we get to changing Class::MOP and Moose to support this.
>>
>> The basic algorithm I've thought of to detect a role-only subclass looks
>> like this. Compare all of this class's attributes and methods to its
>> parent. For any that are specific to the class, see if they come from a
>> role.
>
> This seems like possibly expensive, I wonder if we can't maybe add some more
> meta-data to the metaclass that would maybe track this? This is possibly a
> premature optimization, but I suspect it would also mean you wouldn't have to
> do all the stuff described below too :)
It is almost certainly somewhat expensive. The problem is that there's
really only one optimization path I can think of. If a class is created
via Moose::Meta::Class->create_anon_class, we can know at that point if
it's a role-only subclass, and set a flag which would be unset if any
methods or attributes were added.
However, most classes are not created that way, so this seems like a
narrow-use hack. OTOH, since Moose::Util::MetaRole uses the
create_anon_class API, it'd be sufficient for that need.
There are a couple reasons for doing it the hard and expensive way. First,
tracking the source of attributes and methods seems like a good thing, and
expands the meta API in a potentially useful way. Second, it will work for
situations we haven't foreseen which somehow create these role-only
subclasses.
As far as the speed cost, this would only be paid at compile time. The
expensive check for fixing the metaclass compatibility would not be
invoked in many cases, since the current simple checks ("is MetaA a
subclass of MetaB?") would still be done first, and we'd only fall back to
the complicated check if we had to.
-dave
/*==========================
VegGuide.Org
Your guide to all that's veg
==========================*/