Moose::Spec::Role - Formal spec for Role behavior |
Moose::Spec::Role - Formal spec for Role behavior
This feature was taken from the Fortress language and is really of most use when building a large set of role ``building blocks'' some of which should never be used together.
override
and super
keywords are allowed in roles, but
thier behavior is different from that of it's class counterparts.
The super
in a class refers directly to that class's superclass,
while the super
in a role is deferred and only has meaning once
the role is composed into a class. Once that composition occurs,
super
then refers to that class's superclass.
It is key to remember that roles do not have hierarchy, so they can never have a super role.
before
, around
and after
modifiers provided
in Moose classes. The difference here is that the modifiers are not
actually applied until the role is composed into a class (this is
just like attributes and the override
keyword).
When multiple roles are added to another role (using the
with @roles
keyword) the roles are composed symmetrically.
The product of the composition is a composite role
(the Moose::Meta::Role::Composite manpage).
The reason for such early and harsh conflicts with attributes is because there is so much room for variance between two attributes that the problem quickly explodes and rules get very complex. It is my opinion that this complexity is not worth the trouble.
To look at this in terms of set theory, each role can be said to have a set of methods. The symmetric difference of these two sets is the new set of methods for the composite role, while the intersection of these two sets are the conflicts. This can be illustrated like so:
Role A has method set { a, b, c } Role B has method set { c, d, e } The composite role (A,B) has method set { a, b, d, e } conflict set { c }
The first way is with another overriden method of the same name, and this is considered an un-recoverable error. This is an obvious error since you cannot override a method twice in the same class.
The second way for conflict is for an overriden method and a regular method to have the same name. This is also an un-recoverable error since there is no way to combine these two, nor is it okay for both items to be composed into a single class at some point.
The use of override in roles can be tricky, but if used carefully they can be a very powerful tool.
Since a method can have multiple method modifiers, these are just collected in order to be later applied to the class in that same order.
In general, great care should be taken in using method modifiers in roles. The order sensitivity can possibly lead to subtle and difficult to find bugs if they are overused. As with all good things in life, moderation is the key.
This is a just a set of complex edge cases which can easily get confused. This attempts to clarify those cases and provide an explination of what is going on in them.
Here is an example of this (incorrect) type of overriding.
package Role::Foo; use Moose::Role;
sub foo { ... }
package Role::FooBar; use Moose::Role;
with 'Role::Foo';
sub foo { ... } sub bar { ... }
Here the foo
methods conflict and the Role::FooBar now requires a
class or role consuming it to implement foo
. This is very often not
what the user wants.
Now here is an example of the (correct) type of overriding, only it is not overriding at all, as is explained in the text below.
package Role::Foo; use Moose::Role;
sub foo { ... }
package Role::Bar; use Moose::Role;
sub foo { ... } sub bar { ... }
package Role::FooBar; use Moose::Role;
with 'Role::Foo', 'Role::Bar'; sub foo { ... }
This works because the combination of Role::Foo and Role::Bar produce
a conflict with the foo
method. This conflict results in the
composite role (that was created by the combination of Role::Foo
and Role::Bar using the with keyword) having a method requirement
of foo
. The Role::FooBar then fufills this requirement.
It is important to note that Role::FooBar is simply fufilling the
required foo
method, and **NOT** overriding foo
. This is an
important distinction to make.
Stevan Little <stevan@iinteractive.com>
Copyright 2007-2008 by Infinity Interactive, Inc.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
Moose::Spec::Role - Formal spec for Role behavior |