X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FCookbook%2FWTF.pod;h=c62f3ef84b30b465013e054a2ca58434990b9db1;hb=d03bd989b97597428b460d7f9a021e2931893fa0;hp=b0dfa8a733f5e01e64ede1c2eb552ca5132a50c3;hpb=43b50af34c88c00f35c97282cfcb8f5cd5bd81c4;p=gitmo%2FMoose.git diff --git a/lib/Moose/Cookbook/WTF.pod b/lib/Moose/Cookbook/WTF.pod index b0dfa8a..c62f3ef 100644 --- a/lib/Moose/Cookbook/WTF.pod +++ b/lib/Moose/Cookbook/WTF.pod @@ -11,52 +11,52 @@ Moose::Cookbook::WTF - For when things go wrong with Moose =head3 Why is my code taking so long to load? -Moose does have a compile time performance burden, -which it inherits from Class::MOP. If load/compile -time is a concern for your application, Moose may not -be the right tool for you. +Moose does have a compile time performance burden, +which it inherits from Class::MOP. If load/compile +time is a concern for your application, Moose may not +be the right tool for you. -Although, you should note that we are exploring the -use of L to try and reduce this problem, +Although, you should note that we are exploring the +use of L to try and reduce this problem, but nothing is ready yet. =head3 Why are my objects taking so long to construct? -Moose uses a lot of introspection when constructing an -instance, and introspection can be slow. This problem -can be solved by making your class immutable. This can +Moose uses a lot of introspection when constructing an +instance, and introspection can be slow. This problem +can be solved by making your class immutable. This can be done with the following code: MyClass->meta->make_immutable(); Moose will then memoize a number of meta-level methods -and inline a constructor for you. For more information -on this see the L section below and in the +and inline a constructor for you. For more information +on this see the L section below and in the L. =head2 Constructors & Immutability -=head3 I made my class immutable, but C it is still slow! +=head3 I made my class immutable, but C is still slow! -Do you have a custom C method in your class? Moose -will not overwrite your custom C method, you would -probably do better to try and convert this to use the -C method or possibly set C values in -the attribute declaration. +Do you have a custom C method in your class? Moose +will not overwrite your custom C method, you would +probably do better to try and convert this to use the +C method or possibly set C values in +the attribute declaration. -=head3 I made my class immutable, and now my (before | after | +=head3 I made my class immutable, and now my (before | after | around) C is not being called? -Making a I, I or I wrap around the -C method, will actually create a C method within +Making a I, I or I wrap around the +C method will actually create a C method within your class. This will prevent Moose from creating one itself -when you make the class immutable. +when you make the class immutable. =head2 Accessors =head3 I created an attribute, where are my accessors? -Accessors are B created implicitly, you B ask Moose +Accessors are B created implicitly, you B ask Moose to create them for you. My guess is that you have this: has 'foo' => (isa => 'Bar'); @@ -65,53 +65,53 @@ when what you really want to say is: has 'foo' => (isa => 'Bar', is => 'rw'); -The reason this is so, is because it is a perfectly valid use -case to I have an accessor. The simplest one is that you -want to write your own. If Moose created on automatically, then -because of the order in which classes are constructed, Moose -would overwrite your custom accessor. You wouldn't want that +The reason this is so is because it is a perfectly valid use +case to I have an accessor. The simplest one is that you +want to write your own. If Moose created one automatically, then +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 modifier? +=head3 Why can't I change C<@_> in a C modifier? -The C modifier simply is called I the main method. -Its return values are simply ignored, and are B passed onto -the main method body. +The C modifier is called I the main method. +Its return values are simply ignored, and are B passed onto +the main method body. -There are a number of reasons for this, but those arguments are -too lengthy for this document. Instead, I suggest using an C +There are a number of reasons for this, but those arguments are +too lengthy for this document. Instead, I suggest using an C modifier instead. Here is some sample code: around 'foo' => sub { my $next = shift; my ($self, @args) = @_; - # do something silly here to @args - $next->($self, reverse(@args)); + # do something silly here to @args + $next->($self, reverse(@args)); }; -=head3 How come I can't see return values in an C modifier? +=head3 Why can't I see return values in an C modifier? -As with the C modifier, the C modifier is simply -called I the main method. It is passed the original contents -of C<@_> and B the return values of the main method. +As with the C modifier, the C modifier is simply +called I the main method. It is passed the original contents +of C<@_> and B the return values of the main method. -Again, the arguments are too lengthy as to why this has to be. And +Again, the arguments are too lengthy as to why this has to be. And as with C I recommend using an C modifier instead. Here is some sample code: around 'foo' => sub { my $next = shift; my ($self, @args) = @_; - my @rv = $next->($self, @args); + my @rv = $next->($self, @args); # do something silly with the return values 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 keyword but attributes are checked at compile time @@ -119,7 +119,12 @@ by Perl. To make attributes work, you must place C in a C 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. +=head2 Roles + +=head3 Why is BUILD not called for my composed roles? + +BUILD is never called in composed roles. The primary reason is that +roles are B 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). + +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) + +=item * + +Use attribute triggers, which fire after an attribute is set, to facilitate +initialization. These are described in the L docs, and examples can be +found in the test suite. + +=back + +In general, roles should not I 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 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 Estevan@iinteractive.comE @@ -135,7 +201,7 @@ Anders Nor Berle Edebolaz@gmail.comE =head1 COPYRIGHT AND LICENSE -Copyright 2006, 2007 by Infinity Interactive, Inc. +Copyright 2006-2009 by Infinity Interactive, Inc. L