diff options
Diffstat (limited to 'lib/Moose/Spec/Role.pod')
-rw-r--r-- | lib/Moose/Spec/Role.pod | 397 |
1 files changed, 397 insertions, 0 deletions
diff --git a/lib/Moose/Spec/Role.pod b/lib/Moose/Spec/Role.pod new file mode 100644 index 0000000..f7b288d --- /dev/null +++ b/lib/Moose/Spec/Role.pod @@ -0,0 +1,397 @@ +# PODNAME: Moose::Spec::Role +# ABSTRACT: Formal spec for Role behavior + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +Moose::Spec::Role - Formal spec for Role behavior + +=head1 VERSION + +version 2.1405 + +=head1 DESCRIPTION + +B<NOTE:> This document is currently incomplete. + +=head2 Components of a Role + +=over 4 + +=item Excluded Roles + +A role can have a list of excluded roles, these are basically +roles that they shouldn't be composed with. This is not just +direct composition either, but also "inherited" composition. + +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. + +=item Attributes + +A roles attributes are similar to those of a class, except that +they are not actually applied. This means that methods that are +generated by an attributes accessor will not be generated in the +role, but only created once the role is applied to a class. + +=item Methods + +These are the methods defined within the role. Simple as that. + +=item Required Methods + +A role can require a consuming class (or role) to provide a +given method. Failure to do so for classes is a fatal error, +while for roles it simply passes on the method requirement to +the consuming role. + +=item Required Attributes + +Just as a role can require methods, it can also require attributes. +The requirement fulfilling attribute must implement at least as much +as is required. That means, for instance, that if the role requires +that the attribute be read-only, then it must at least have a reader +and can also have a writer. It means that if the role requires that +the attribute be an ArrayRef, then it must either be an ArrayRef or +a subtype of an ArrayRef. + +=item Overridden Methods + +The C<override> and C<super> keywords are allowed in roles, but +their behavior is different from that of its class counterparts. +The C<super> in a class refers directly to that class's superclass, +while the C<super> in a role is deferred and only has meaning once +the role is composed into a class. Once that composition occurs, +C<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 I<super> role. + +=item Method Modifiers + +These are the C<before>, C<around> and C<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 C<override> keyword). + +=back + +=head2 Role Composition + +=head3 Composing into a Class + +=over 4 + +=item Excluded Roles + +=item Required Methods + +=item Required Attributes + +=item Attributes + +=item Methods + +=item Overridden methods + +=item Method Modifiers (before, around, after) + +=back + +=head3 Composing into a Instance + +=head3 Composing into a Role + +=over 4 + +=item Excluded Roles + +=item Required Methods + +=item Required Attributes + +=item Attributes + +=item Methods + +=item Overridden methods + +=item Method Modifiers (before, around, after) + +=back + +=head3 Role Summation + +When multiple roles are added to another role (using the +C<with @roles> keyword) the roles are composed symmetrically. +The product of the composition is a composite role +(L<Moose::Meta::Role::Composite>). + +=over 4 + +=item Excluded Roles + +=item Required Methods + +=item Required Attributes + +=item Attributes + +Attributes with the same name will conflict and are considered +a unrecoverable error. No other aspect of the attribute is +examined, it is enough that just the attribute names conflict. + +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. + +=item Methods + +Methods with the same name will conflict, but no error is +thrown, instead the method name is added to the list of +I<required> methods for the new composite role. + +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 } + +=item Overridden methods + +An overridden method can conflict in one of two ways. + +The first way is with another overridden method of the same +name, and this is considered an unrecoverable 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 overridden method and a +regular method to have the same name. This is also an unrecoverable +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. + +=item Method Modifiers (before, around, after) + +Method modifiers are the only place where the ordering of +role composition matters. This is due to the nature of +method modifiers themselves. + +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. + +=back + +=head3 Composition Edge Cases + +This is a just a set of complex edge cases which can easily get +confused. This attempts to clarify those cases and provide an +explanation of what is going on in them. + +=over 4 + +=item Role Method Overriding + +Many people want to "override" methods in roles they are consuming. +This works fine for classes, since the local class method is favored +over the role method. However in roles it is trickier, this is because +conflicts result in neither method being chosen and the method being +"required" instead. + +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 C<foo> methods conflict and the Role::FooBar now requires a +class or role consuming it to implement C<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 C<foo> method. This conflict results in the +composite role (that was created by the combination of Role::Foo +and Role::Bar using the I<with> keyword) having a method requirement +of C<foo>. The Role::FooBar then fulfills this requirement. + +It is important to note that Role::FooBar is simply fulfilling the +required C<foo> method, and **NOT** overriding C<foo>. This is an +important distinction to make. + +Now here is another example of a (correct) type of overriding, this +time using the I<excludes> option. + + package Role::Foo; + use Moose::Role; + + sub foo { ... } + + package Role::FooBar; + use Moose::Role; + + with 'Role::Foo' => { -excludes => 'foo' }; + + sub foo { ... } + sub bar { ... } + +By specifically excluding the C<foo> method during composition, +we allow B<Role::FooBar> to define its own version of C<foo>. + +=back + +=head1 SEE ALSO + +=over 4 + +=item Traits + +Roles are based on Traits, which originated in the Smalltalk +community. + +=over 4 + +=item L<http://www.iam.unibe.ch/~scg/Research/Traits/> + +This is the main site for the original Traits papers. + +=item L<Class::Trait> + +I created this implementation of traits several years ago, +after reading the papers linked above. (This module is now +maintained by Ovid and I am no longer involved with it). + +=back + +=item Roles + +Since they are relatively new, and the Moose implementation +is probably the most mature out there, roles don't have much +to link to. However, here is some bits worth looking at (mostly +related to Perl 6) + +=over 4 + +=item L<http://www.oreillynet.com/onlamp/blog/2006/08/roles_composable_units_of_obje.html> + +This is chromatic's take on roles, which is worth reading since +he was/is one of the big proponents of them. + +=item L<http://svn.perl.org/perl6/doc/trunk/design/syn/S12.pod> + +This is Synopsis 12, which is all about the Perl 6 Object System. +Which, of course, includes roles. + +=back + +=back + +=head1 AUTHORS + +=over 4 + +=item * + +Stevan Little <stevan.little@iinteractive.com> + +=item * + +Dave Rolsky <autarch@urth.org> + +=item * + +Jesse Luehrs <doy@tozt.net> + +=item * + +Shawn M Moore <code@sartak.org> + +=item * + +יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org> + +=item * + +Karen Etheridge <ether@cpan.org> + +=item * + +Florian Ragwitz <rafl@debian.org> + +=item * + +Hans Dieter Pearcey <hdp@weftsoar.net> + +=item * + +Chris Prather <chris@prather.org> + +=item * + +Matt S Trout <mst@shadowcat.co.uk> + +=back + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2006 by Infinity Interactive, Inc.. + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + +=cut |