X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FCookbook%2FFAQ.pod;h=1fff37c7de522b6c18015681ba4b3a23e51f3f50;hb=c698114db4728fe80824c4401544f1e1b9749de4;hp=e9aeb6f190e670c59461ccda531ccc87bb15f92f;hpb=ce21ecc578e3154f99399f49bde10e93bf390afa;p=gitmo%2FMoose.git diff --git a/lib/Moose/Cookbook/FAQ.pod b/lib/Moose/Cookbook/FAQ.pod index e9aeb6f..1fff37c 100644 --- a/lib/Moose/Cookbook/FAQ.pod +++ b/lib/Moose/Cookbook/FAQ.pod @@ -11,42 +11,42 @@ Moose::Cookbook::FAQ - Frequently asked questions about Moose =head3 Is Moose "production ready"? -Yes. I have several medium-to-large-ish web applications in -production using Moose, they have been running without -issue now for well over a year. +Yes! Many sites with household names are using Moose to build +high-traffic services. Countless others are using Moose in +production. -At C<$work> we are re-writing our core offering to use Moose, -so it's continued development is assured. - -Several other people on #moose either have apps in production -which use Moose, or are in the process of deploying sites -which use Moose. +As of this writing, Moose is a dependency of several hundred CPAN +modules. L =head3 Is Moose's API stable? -Yes and No. The external API, the one 90% of users will interact -with, is B and any changes B. The introspection API is I stable; I still -reserve the right to tweak that if needed, but I will do my -absolute best to maintain backwards compatibility here as well. +Yes. The sugary API, the one 95% of users will interact with, is +B. Any changes will be B<100% backwards compatible>. + +The meta API is less set in stone. We reserve the right to tweak +parts of it to improve efficiency or consistency. This will not be +done lightly. We do perform deprecation cycles. We I +do not like making ourselves look bad by breaking your code. +Submitting test cases is the best way to ensure that your code is not +inadvertantly broken by refactoring. =head3 I heard Moose is slow, is this true? Again, this one is tricky, so Yes I No. -First let me say that I in life is free, and that some -Moose features do cost more than others. It is also the -policy of Moose to B, -and to do our absolute best to not place any extra burdens on -the execution of your code for features you are not using. Of -course using Moose itself does involve some overhead, but it -is mostly compile time. At this point we do have some options -available for getting the speed you need. - -Currently we have the option of making your classes immutable -as a means of boosting speed. This will mean a slightly larger compile +First let me say that I in life is free, and that some +Moose features do cost more than others. It is also the +policy of Moose to B, +and to do our absolute best to not place any extra burdens on +the execution of your code for features you are not using. Of +course using Moose itself does involve some overhead, but it +is mostly compile time. At this point we do have some options +available for getting the speed you need. + +Currently we have the option of making your classes immutable +as a means of boosting speed. This will mean a slightly larger compile time cost, but the runtime speed increase (especially in object -construction) is pretty significant. This is not very well +construction) is pretty significant. This is not very well documented yet, so please ask on the list or on #moose for more information. @@ -67,15 +67,15 @@ Ideally, you should never write your own C method, and should use Moose's other features to handle your specific object construction needs. Here are a few scenarios, and the Moose way to solve them; -If you need to call initialization code post instance construction, -then use the C method. This feature is taken directly from -Perl 6. Every C method in your inheritance chain is called -(in the correct order) immediately after the instance is constructed. -This allows you to ensure that all your superclasses are initialized +If you need to call initialization code post instance construction, +then use the C method. This feature is taken directly from +Perl 6. Every C method in your inheritance chain is called +(in the correct order) immediately after the instance is constructed. +This allows you to ensure that all your superclasses are initialized properly as well. This is the best approach to take (when possible) -because it makes sub classing your class much easier. +because it makes subclassing your class much easier. -If you need to affect the constructor's parameters prior to the +If you need to affect the constructor's parameters prior to the instance actually being constructed, you have a number of options. To change the parameter processing as a whole, you can use @@ -84,28 +84,40 @@ pairs or a hash reference. You can override it to take positional args, or any other format To change the handling of individual parameters, there are I -(See the L for a complete example and -explaination of coercions). With coercions it is possible to morph +(See the L for a complete example and +explanation of coercions). With coercions it is possible to morph argument values into the correct expected types. This approach is the most flexible and robust, but does have a slightly higher learning curve. -=head3 How do I make non-Moose constructors work with Moose? +=head3 How do I make non-Moose constructors work with Moose? + +Usually the correct approach to subclassing a non Moose class is +delegation. Moose makes this easy using the C keyword, +coercions, and C, so subclassing is often not the +ideal route. + +That said, the default Moose constructor is inherited from +L. When inheriting from a non-Moose class, the +inheritance chain to L is broken. The simplest way +to fix this is to simply explicitly inherit from L +yourself. -Moose provides its own constructor, but it does it by making all -Moose-based classes inherit from L. When inheriting -from a non-Moose class, the inheritance chain to L -is broken. The simplest way to fix this is to simply explicitly -inherit from L yourself. However, this does not -always fix the issue of a constructor. Here is a basic example of -how this can be worked around: +However, this does not always fix the issue of actually calling the Moose +constructor. Fortunately, the modules L and +L aim to make subclassing non-Moose classes easier. + +If neither extension fills your specific needs, you can use +L. This low-level constructor accepts the +special C<__INSTANCE__> parameter, allowing you to instantiate your Moose +attributes: package My::HTML::Template; use Moose; - - # explicit inheritance + + # explicit inheritance extends 'HTML::Template', 'Moose::Object'; - + # explicit constructor sub new { my $class = shift; @@ -114,93 +126,92 @@ how this can be worked around: return $class->meta->new_object( # pass in the constructed object # using the special key __INSTANCE__ - __INSTANCE__ => $obj, @_ + __INSTANCE__ => $obj, + @_, # pass in the normal args ); } -Of course, this only works if both your Moose class and the -inherited non-Moose class use the same instance type (typically -HASH refs). +Of course, this only works if both your Moose class and the +inherited non-Moose class use the same instance type (typically +HASH refs). -Other techniques can be used as well, such as creating the object -using C, but calling the inherited non-Moose -class's initialization methods (if available). +Note that this doesn't call C automatically, you must do that +yourself. -It is also entirely possible to just rely on HASH autovivification -to create the slots needed for Moose based attributes, although this -does restrict use of construction time attribute features somewhat. +Other techniques can be used as well, such as creating the object +using C, but calling the inherited non-Moose +class's initialization methods (if available). -In short, there are several ways to go about this, it is best to -evaluate each case based on the class you wish to extend, and the -features you wish to employ. As always, both IRC and the mailing -list are great ways to get help finding the best approach. +In short, there are several ways to extend non-Moose classes. It is +best to evaluate each case based on the class you wish to extend, +and the features you wish to employ. As always, both IRC and the +mailing list are great ways to get help finding the best approach. =head2 Accessors =head3 How do I tell Moose to use get/set accessors? -The easiest way to accomplish this is to use the C and +The easiest way to accomplish this is to use the C and C attribute options. Here is some example code: has 'bar' => ( isa => 'Baz', - reader => 'get_bar', + reader => 'get_bar', writer => 'set_bar', ); -Moose will still take advantage of type constraints, triggers, etc. -when creating these methods. +Moose will still take advantage of type constraints, triggers, etc. +when creating these methods. -If you do not like this much typing, and wish it to be a default for -your class, please see L, and more specifically -L. This will allow you to write: +If you do not like this much typing, and wish it to be a default for your +class, please see L. This will allow you to write: has 'bar' => ( isa => 'Baz', is => 'rw', ); -And have Moose create seperate C and C methods +And have Moose create separate C and C methods instead of a single C method. -NOTE: This B be set globally in Moose, as that would break +NOTE: This B be set globally in Moose, as that would break other classes which are built with Moose. =head3 How can I get Moose to inflate/deflate values in the accessor? -Well, the first question to ask is if you actually need both inflate +Well, the first question to ask is if you actually need both inflate and deflate. -If you only need to inflate, then I suggest using coercions. Here is +If you only need to inflate, then I suggest using coercions. Here is some basic sample code for inflating a L object: subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') }; - + coerce 'DateTime' => from 'Str' => via { DateTime::Format::MySQL->parse_datetime($_) }; - + has 'timestamp' => (is => 'rw', isa => 'DateTime', coerce => 1); -This creates a custom subtype for L objects, then attaches -a coercion to that subtype. The C attribute is then told +This creates a custom subtype for L objects, then attaches +a coercion to that subtype. The C attribute is then told to expect a C type, and to try to coerce it. When a C -type is given to the C accessor, it will attempt to -coerce the value into a C object using the code in found -in the C block. +type is given to the C accessor, it will attempt to +coerce the value into a C object using the code in found +in the C block. For a more comprehensive example of using coercions, see the -L. +L. -If you need to deflate your attribute, the current best practice is to +If you need to deflate your attribute, the current best practice is to add an C modifier to your accessor. Here is some example code: - # a timestamp which stores as + # a timestamp which stores as # seconds from the epoch has 'timestamp' => (is => 'rw', isa => 'Int'); - + around 'timestamp' => sub { my $next = shift; my ($self, $timestamp) = @_; @@ -208,28 +219,28 @@ add an C modifier to your accessor. Here is some example code: $next->($self, $timestamp->epoch); }; -It is also possible to do deflation using coercion, but this tends -to get quite complex and require many subtypes. An example of this -is outside the scope of this document, ask on #moose or send a mail +It is also possible to do deflation using coercion, but this tends +to get quite complex and require many subtypes. An example of this +is outside the scope of this document, ask on #moose or send a mail to the list. -Still another option is to write a custom attribute metaclass, which -is also outside the scope of this document, but I would be happy to +Still another option is to write a custom attribute metaclass, which +is also outside the scope of this document, but I would be happy to explain it on #moose or the mailing list. =head2 Method Modifiers =head3 How can I affect the values in C<@_> using C? -You can't, actually: C only runs before the main method, -and it cannot easily affect the method's execution. What you want is -an C method. +You can't, actually: C only runs before the main method, +and it cannot easily affect the method's execution. What you want is +an C method. =head3 Can I use C to stop execution of a method? -Yes, but only if you throw an exception. If this is too drastic a -measure then I suggest using C instead. The C method -modifier is the only modifier which can gracefully prevent execution +Yes, but only if you throw an exception. If this is too drastic a +measure then I suggest using C instead. The C method +modifier is the only modifier which can gracefully prevent execution of the main method. Here is an example: around 'baz' => sub { @@ -241,7 +252,7 @@ of the main method. Here is an example: $next->($self, %options); }; -By choosing not to call the C<$next> method, you can stop the +By choosing not to call the C<$next> method, you can stop the execution of the main method. =head2 Type Constraints @@ -250,25 +261,40 @@ execution of the main method. Use the C option when building the subtype, like so: - subtype 'NaturalLessThanTen' + subtype 'NaturalLessThanTen' => as 'Natural' => where { $_ < 10 } => message { "This number ($_) is not less than ten!" }; This will be called when a value fails to pass the C -constraint check. +constraint check. =head3 Can I turn off type constraint checking? -Not yet, but soon. This option will likely be coming in the next +Not yet, but soon. This option will likely be coming in the next release. =head2 Roles =head3 How do I get Moose to call BUILD in all my composed roles? -See L and specifically the B question in the B section. +See L and specifically the B question in the B section. + +=head3 What are Traits, and how are they different from Roles? + +In Moose, a trait is almost exactly the same thing as a role, except +that traits typically register themselves, which allows you to refer +to them by a short name ("Big" vs "MyApp::Role::Big"). + +In Moose-speak, a I is usually composed into a I at +compile time, whereas a I is usually composed into an instance +of a class at runtime to add or modify the behavior of B. + +Outside the context of Moose, traits and roles generally mean exactly the +same thing. The original paper called them Traits, however Perl 6 will call +them Roles. =head1 AUTHOR @@ -276,7 +302,7 @@ Stevan Little Estevan@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2006-2008 by Infinity Interactive, Inc. +Copyright 2006-2009 by Infinity Interactive, Inc. L