Based on discussion with Stevan, I've made some major changes to my
branches.
In the CMOP topic/mi-methods-attributes branch, the HasMethods and
HasAttributes classes are now under CMOP::Mixin::.
They still inherit from CMOP::Object, because they need to have a ->meta
method. I could change that (maybe have a separate CMOP::Mixin parent?),
but that's a small detail.
In this branch, there is also a new mixin class with the unfortunate name
of CMOP::Mixin::AttributeBase. I hate calling it "Base" so suggestions are
welcome. Basically, I've moved the attributes of the meta-attribute class
into a separate mixin for the benefit of role attributes.
This AttributeBase class is all properties and very little behavior. The
behavior is still mostly in CMOP::Attribute and MM::Attribute.
Again, a better name is welcome, but I think the idea is sound.
In the Moose topic/roles-have-real-attributes branch, I've made a lot more
changes.
Instead of using a trait to make role attributes special, they are now
their own class. The hierarchy for attributes looks like this:
CMOP::Mixin::AttributeBase
/ \
CMOP::Attribute Moose::Meta::Mixin::AttributeBase
\ / \
Moose::Meta::Attribute Moose::Meta::Role::Attribute
Yay, diamond inheritance. Yes, it's disturbing, but if you think of the
mixins as roles it's a little less horrible.
Again, the AttributeBase mixin in Moose captures attribute properties,
while MM::Attribute provides behavior.
The role attribute now knows how to make a "real" attribute for classes,
given an attribute metaclass, like this:
$role_attr->attribute_for_class($attr_metaclass)
This is called during role application to a class, and can _also_ be
called at some other time in order to get more information out of the role
attribute.
By itself, the role attribute doesn't do much, it just captures the
options passed to "has".
This is a little weird, because it means that things like
$role_attr->reader will generally return undef, because it doesn't process
the "is" option.
You might think "why not just make a real attribute", but the answer is
that without knowing what attribute metaclass to use, making a real
attribute won't get the right answer.
A concrete example of this problem can be seen with MX::FollowPBP. When
that MX is used, it applies a meta-attr trait that changes how "is" is
processed. This means that you can only know the real method names in the
context of a specific "real" attribute metaclass.
This means that introspection on the role attribute is really not complete
unless you can supply an attribute metaclass. However, given our future
goal of generating method conflicts _when applying role attributes to a
class_, this is fine. When we do that application, we can ask the class
for its metaclass, figure out all the method names that will be generated,
and look for conflicts.
Note that this conflict detection is not yet implemented. That's the next
step, but I'd like to get these changes merged as-is.
So please review the above-mentioned branches.
-dave
/*============================================================
http://VegGuide.org http://blog.urth.org
Your guide to all that's veg House Absolute(ly Pointless)
============================================================*/