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

Reply via email to