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
==========================*/