X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FCookbook%2FFAQ.pod;h=6ff53af826d725a7cab529de27a7d25bbfc89d8c;hb=37a9448b781fec00a31fed31130b3531c4029a30;hp=69a972c424f55d5dcfd4d4b563e99f59e2c56b0d;hpb=4711f5f709b4363d26ed39068155e74addb247f2;p=gitmo%2FMoose.git diff --git a/lib/Moose/Cookbook/FAQ.pod b/lib/Moose/Cookbook/FAQ.pod index 69a972c..6ff53af 100644 --- a/lib/Moose/Cookbook/FAQ.pod +++ b/lib/Moose/Cookbook/FAQ.pod @@ -11,60 +11,54 @@ Moose::Cookbook::FAQ - Frequently asked questions about Moose =head3 Is Moose "production ready"? -Yes. I have two medium-to-large-ish web applications in -production using Moose, they have been running without -issue now for almost a year. +Yes! Many sites with household names are using Moose to build +high-traffic services. Countless others are using Moose in +production. -At $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 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 -documented yet, so please ask on the list of on #moose for more +construction) is pretty significant. This is not very well +documented yet, so please ask on the list or on #moose for more information. -We are also discussing and experimenting with L, -and the idea of compiling highly optimized C<.pmc> files. And -we have also mapped out some core methods as candidates for -conversion to XS. +We are also discussing and experimenting with L, +and the idea of compiling highly optimized C<.pmc> files. In +addition, we have mapped out some core methods as candidates for +conversion to XS. -=head3 When will Moose be 1.0 ready? +=head3 When will Moose 1.0 be ready? -I had originally said it would be end of 2006, but various bits -of $work kept me too busy. At this point, I think we are getting -pretty close and I will likely declare 1.0 within the next few -releases. - -When will that be? Hard to say really, but honestly, it is ready -to use now, the difference between now and 1.0 will be pretty -minimal. +Moose is ready now! Stevan Little declared 0.18, released in March 2007, +to be "ready to use". =head2 Constructors @@ -74,54 +68,57 @@ 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. -First, there are I (See the L -for a complete example and explaination 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. - -Second, using an C method modifier on C can be an -effective way to affect the contents of C<@_> prior to letting -Moose deal with it. This carries with it the extra burden for -your subclasses, in that they have to be sure to explicitly -call your C and/or work around your C to get to the -version from L. - -The last approach is to use the standard Perl technique of calling -the C within your own custom version of C. This -of course brings with it all the issues of the C solution -along with any issues C might add as well. - -In short, try to use C and coercions, they are your best -bets. - -=head3 How do I make non-Moose constructors work with Moose? - -Moose provides it's 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: +To change the parameter processing as a whole, you can use +the C method. The default implementation accepts key/value +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 +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? + +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. + +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; @@ -130,94 +127,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 slot's needed for Moose based attributes. Although -this does somewhat restrict use of construction time attribute -features. +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 the -L. This will allow you to write this: +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 C and C instead of the usual -C. +And have Moose create separate C and C methods +instead of a single C method. -NOTE: This B be set globally in Moose, as this 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 -some basic sample code for inflating a L object. +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 -to expect a C type, and to try and 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. +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. -For a more detailed and complete example of coercions, see the -L. +For a more comprehensive example of using coercions, see the +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) = @_; @@ -225,74 +220,103 @@ 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 execution of it. 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. + +You similarly can't use C to affect the return value of a +method. + +We limit C and C because this lets you write more +concise code. You do not have to worry about passing C<@_> to the +original method, or forwarding its response (being careful to preserve +context). + +The C method modifier has neither of these limitations. =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 actually stop the 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 { my $next = shift; my ($self, %options) = @_; - if ($options{bar} eq 'foo') { - $next->($self, %options); - } - else { - return 'bar'; + unless ($options->{bar} eq 'foo') { + return 'bar'; } + $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 =head3 How can I have a custom error message for a type constraint? -Use the C option when building the subtype. Like so: +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 type constraint checking off? +=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. + +=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 Stevan Little Estevan@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2006, 2007 by Infinity Interactive, Inc. +Copyright 2006-2009 by Infinity Interactive, Inc. L This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. -=cut \ No newline at end of file +=cut