Clarify that this wtf is about subroutine attributes
[gitmo/Moose.git] / lib / Moose / Cookbook / WTF.pod
index b0dfa8a..4b07bcd 100644 (file)
@@ -72,7 +72,7 @@ because of the order in which classes are constructed, Moose
 would overwrite your custom accessor. You wouldn't want that 
 would you?
 
-=head2 Method Modfiers
+=head2 Method Modifiers
 
 =head3 How come I can't change C<@_> in a C<before> modifier?
 
@@ -109,9 +109,9 @@ Here is some sample code:
       return reverse @rv;
   };
 
-=head2 Moose and Attributes
+=head2 Moose and Subroutine Attributes
 
-=head3 Why doesn't attributes I inherited from a superclass work?
+=head3 Why don't subroutine attributes I inherited from a superclass work?
 
 Currently when you subclass a module, this is done at runtime with
 the C<extends> keyword but attributes are checked at compile time
@@ -119,7 +119,12 @@ by Perl. To make attributes work, you must place C<extends> in a
 C<BEGIN> block so that the attribute handlers will be available at
 compile time like this:
 
-  BEGIN { extends qw/Foo/ } 
+  BEGIN { extends qw/Foo/ }
+
+Note that we're talking about Perl's subroutine attributes here, not
+Moose attributes:
+
+  sub foo : Bar(27) { ... }
 
 =head2 Moose and Other Modules
 
@@ -127,6 +132,67 @@ compile time like this:
 
 See L<Moose and Attributes>.
 
+=head2 Roles
+
+=head3 How come BUILD is not called for my composed roles?
+
+BUILD is never called in composed roles. The primary reason is that 
+roles are B<not> order sensitive. Roles are composed in such a way 
+that the order of composition does not matter (for information on 
+the deeper theory of this read the original traits papers here 
+L<http://www.iam.unibe.ch/~scg/Research/Traits/>). 
+
+Because roles are essentially unordered, it would be impossible to 
+determine the order in which to execute the BUILD methods. 
+
+As for alternate solutions, there are a couple.
+
+=over 4
+
+=item * 
+
+Using a combination of lazy and default in your attributes to 
+defer initialization (see the Binary Tree example in the cookbook
+for a good example of lazy/default usage
+L<Moose::Cookbook::Basics::Recipe3>)
+
+=item *
+
+Use attributes triggers, which fire after an attribute it set, to facilitate 
+initialization. These are described in the L<Moose> docs and examples can be 
+found in the test suite.
+
+=back
+
+In general, roles should not I<require> initialization, they should either 
+provide sane defaults or should be documented as needing specific 
+initialization. One such way to "document" this is to have a separate
+attribute initializer which is required for the role. Here is an example of 
+how to do this:
+
+  package My::Role;
+  use Moose::Role;
+  
+  has 'height' => (
+      is      => 'rw',
+      isa     => 'Int',
+      lazy    => 1,
+      default => sub {
+          my $self = shift;
+          $self->init_height;
+      } 
+  );
+  
+  requires 'init_height';
+
+In this example, the role will not compose successfully unless the class 
+provides a C<init_height> method. 
+
+If none of those solutions work, then it is possible that a role is not 
+the best tool for the job, and you really should be using classes. Or, at
+the very least, you should reduce the amount of functionality in your role
+so that it does not require initialization.
+
 =head1 AUTHOR
 
 Stevan Little E<lt>stevan@iinteractive.comE<gt>
@@ -135,7 +201,7 @@ Anders Nor Berle E<lt>debolaz@gmail.comE<gt>
 
 =head1 COPYRIGHT AND LICENSE
 
-Copyright 2006, 2007 by Infinity Interactive, Inc.
+Copyright 2006-2009 by Infinity Interactive, Inc.
 
 L<http://www.iinteractive.com>