Document how to pass new attribute values at instance-role application time
[gitmo/Moose.git] / lib / Moose / Manual / Roles.pod
index fdd1144..009a2ea 100644 (file)
@@ -1,19 +1,21 @@
-=pod
+package Moose::Manual::Roles;
+
+# ABSTRACT: Roles, an alternative to deep hierarchies and base classes
 
-=head1 NAME
+__END__
 
-Moose::Manual::Roles - Roles, an alternative to deep hierarchies and base classes
+=pod
 
 =head1 WHAT IS A ROLE?
 
-A role is something that classes do. Usually, a role encapsulates some
-piece of behavior or state that can be shared between classes. It is
-important to understand that I<roles are not classes>. You cannot
-inherit from a role, and a role cannot be instantiated. We sometimes
-say that roles are I<consumed>, either by classes or other roles.
+A role encapsulates some piece of behavior or state that can be shared between
+classes. It is something that classes I<do>. It is important to understand that
+I<roles are not classes>. You cannot inherit from a role, and a role cannot be
+instantiated. We sometimes say that roles are I<consumed>, either by classes
+or other roles.
 
 Instead, a role is I<composed> into a class. In practical terms, this
-means that all of the methods and attributes defined in a role are
+means that all of the methods, method modifiers, and attributes defined in a role are
 added directly to (we sometimes say "flattened into") the class that
 consumes the role. These attributes and methods then appear as if they
 were defined in the class itself. A subclass of the consuming class
@@ -28,7 +30,7 @@ methods, in which case the role would be very much like a Java
 interface.
 
 Note that attribute accessors also count as methods for the
-purposes of satisfying the requirements of a role. 
+purposes of satisfying the requirements of a role.
 
 =head1 A SIMPLE ROLE
 
@@ -100,7 +102,7 @@ We could use this same role in a C<Bone> class:
       isa => 'Marrow',
   );
 
-See also L<Moose::Cookbook::Roles::Recipe1> for an example.
+See also L<Moose::Cookbook::Roles::Comparable_CodeReuse> for an example.
 
 =head1 REQUIRED METHODS
 
@@ -173,10 +175,10 @@ interface.
 
 =head2 Required Attributes
 
-As mentioned before, a role requirement may also be satisfied by an
-attribute accessor. But any C<has> functions, which will generate
-accessors that satisfy the role requirement, must be placed
-I<before> the C<with> function that composes the role.
+As mentioned before, a role's required method may also be satisfied by an
+attribute accessor. However, the call to C<has> which defines an attribute
+happens at runtime. This means that you must define the attribute I<before>
+consuming the role, or else the role will not see the generated accessor.
 
   package Breakable;
 
@@ -188,7 +190,7 @@ I<before> the C<with> function that composes the role.
 
   use Moose;
 
-  has 'stress' => ( 
+  has 'stress' => (
       is  => 'rw',
       isa => 'Int',
   );
@@ -214,7 +216,7 @@ in the same order as the roles are used:
 
   with 'Breakable', 'ExplodesOnBreakage';
 
-Assuming that the new C<ExplodesOnBreakage> method I<also> has an
+Assuming that the new C<ExplodesOnBreakage> role I<also> has an
 C<after> modifier on C<break>, the C<after> modifiers will run one
 after the other. The modifier from C<Breakable> will run first, then
 the one from C<ExplodesOnBreakage>.
@@ -290,7 +292,7 @@ probably expects it to implement that method.
 In some use cases we might alias and exclude methods from roles, but
 then provide a method of the same name in the class itself.
 
-Also see L<Moose::Cookbook::Roles::Recipe2> for an example.
+Also see L<Moose::Cookbook::Roles::Restartable_AdvancedComposition> for an example.
 
 =head1 ROLE EXCLUSION
 
@@ -304,49 +306,14 @@ the role.
 
   excludes 'BreakDancer';
 
-=head1 APPLYING ROLES
-
-A role can be applied to a class or an instance in other ways besides
-using the 'with' syntax.
-
-To apply a role to a class, use L<Moose::Util> and the 'apply_all_roles'
-function. If you apply the role to a class, it will affect all objects of that
-class. You can't apply a role to a class if it has been made immutable. In
-some circumstances it may make sense to make the class mutable, apply the role,
-then make the class immutable again.
-
-   use Moose::Util;
-   ...
-   my $class = 'MyApp::Test';
-   $class->meta->make_mutable;
-   Moose::Util::apply_all_roles($class->meta, ('MyApp::SomeRole'));
-   $class->meta->make_immutable;
-
-Do not apply roles to classes that have immutable subclasses, since that
-will invalidate the metadata of the subclasses.
-
-If you want the role to be applied only to a particular instance and not to the
-class, you can apply the roles to the instance instead of the class's meta:
-
-   Moose::Util::apply_all_roles($instance, ('MyApp::SomeRole'));
-
-Or you can use the role's meta object:
-
-   MyApp::SomeRole->meta->apply($instance);
-
-The mutable/immutable state is not relevant to roles applied to instances. 
-See L<Moose::Role> and L<Moose::Util> for more details and 
-L<Moose::Cookbook::Roles::Recipe3> for a more developed example.
-
 =head1 ADDING A ROLE TO AN OBJECT INSTANCE
 
-Sometimes you may want to add a role to an object instance, rather than to a
-class. For example, you may want to add debug tracing to one instance of an
-object while debugging a particular bug. Another use case might be to
-dynamically change objects based on a user's configuration, as a plugin
-system.
+You may want to add a role to an object instance, rather than to a class. For
+example, you may want to add debug tracing to one instance of an object while
+debugging a particular bug. Another use case might be to dynamically change
+objects based on a user's configuration, as a plugin system.
 
-The best way to do this is to use the C<apply_all_roles> function from
+The best way to do this is to use the C<apply_all_roles()> function from
 L<Moose::Util>:
 
   use Moose::Util qw( apply_all_roles );
@@ -359,17 +326,45 @@ normal Moose role combination system. We recommend using this function to
 apply roles to an object. This is what Moose uses internally when you call
 C<with>.
 
-=head1 AUTHOR
+=head2 Handling required attributes for roles.
+
+Application of some roles will require additional parameters being specified to
+satisfy them, for example:
+
+    {
+        package Car;
+        use Moose;
+    }
+    {
+        package Breakable;
+        use Moose::Role;
+
+        has 'breakable_parts' => ( is => 'ro', required => 1 );
+    }
+
+    my $car = Car->new;
+
+    # next line dies with: Attribute (breakable_parts) is required
+    apply_all_roles( $car, 'Breakable' );
 
-Dave Rolsky E<lt>autarch@urth.orgE<gt>
+This will require passing the additional parameters at application time as
+follows:
 
-=head1 COPYRIGHT AND LICENSE
+    apply_all_roles( $car, 'Breakable' => {
+            rebless_params => {
+                # Parameters to 'Breakable'
+                breakable_parts => [qw( tires wheels windscreen )],
+            }
+    });
 
-Copyright 2009 by Infinity Interactive, Inc.
+Obviously, this interface is better simplified as a method on C<Car>:
 
-L<http://www.iinteractive.com>
+    sub make_breakable {
+        my ( $self, %params ) = @_;
+        apply_all_roles($self, 'Breakable', { rebless_params => \%params });
+    }
 
-This library is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
+    my $car = Car->new();
+    $car->make_breakable( breakable_parts => [qw( tires wheels windscreen )] );
 
 =cut