X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FManual%2FBestPractices.pod;h=f0edc9b0d40ad27db38288f84e285ead7cf88f75;hb=d5f016af3d56eec870efee8858352a4014879be2;hp=2b4fd1b1eb116aafe1c9ef4aecd1cf7ff9ff51c6;hpb=7b307c3e1ca2b21164267214ad04167e4ce86ff8;p=gitmo%2FMoose.git diff --git a/lib/Moose/Manual/BestPractices.pod b/lib/Moose/Manual/BestPractices.pod index 2b4fd1b..f0edc9b 100644 --- a/lib/Moose/Manual/BestPractices.pod +++ b/lib/Moose/Manual/BestPractices.pod @@ -13,27 +13,34 @@ and using them consistently makes everyone's life easier. Of course, as with any list of "best practices", these are really just opinions. Feel free to ignore us. -=head2 C and immutabilize +=head2 C and immutabilize -We recommend that you end your Moose class definitions by removing the -Moose sugar and making your class immutable. +We recommend that you remove the Moose sugar and end your Moose class +definitions by making your class immutable. package Person; use Moose; + use namespace::autoclean; # extends, roles, attributes, etc. # methods - no Moose; - __PACKAGE__->meta->make_immutable; 1; -The C bit is simply good code hygiene, and making classes -immutable speeds up a lot of things, most notably object construction. +The C bit is simply good code hygiene, as it removes +imported symbols from you class's namespace at the end of your package's +compile cycle, including Moose keywords. Once the class has been +built, these keywords are not needed needed. The C +call allows Moose to speed up a lot of things, most notably object +construction. The trade-off is that you can no longer change the class +definition. + +C may be used to unimport only Moose's imported symbols. +L provides finer-grained control than L. =head2 Never override C @@ -84,7 +91,7 @@ Also, keep your builder methods private. Lazy is good, and often solves initialization ordering problems. It's also good for deferring work that may never have to be done. If you're -going to be lazy, use I to save yourself some typing and +going to be lazy, use C to save yourself some typing and standardize names. =head2 Consider keeping clearers and predicates private @@ -106,6 +113,15 @@ If you I make an attribute read-write, consider making the writer a separate private method. Narrower APIs are easy to maintain, and mutable state is trouble. +In order to declare such attributes, provide a private C +parameter: + + has pizza => ( + is => 'ro', + isa => 'Pizza', + writer => '_pizza', + ); + =head2 Think twice before changing an attribute's type in a subclass Down this path lies great confusion. If the attribute is an object @@ -116,13 +132,12 @@ of object in the parent class. Don't know what we're talking about? That's fine. -=head2 Use L instead of C +=head2 Use L traits instead of C The C feature is a bit troublesome. Directly exposing a complex attribute is ugly. Instead, consider using -L to define an API that exposes those pieces -of functionality that need exposing. Then you can expose just the -functionality that you want. +L traits to define an API that exposes only +necessary pieces of functionality. =head2 Always call C in the most specific subclass @@ -137,8 +152,8 @@ Use some sort of namespacing convention for type names. We recommend something like "MyApp::Type::Foo". If you're intending to package your types up for re-use using -MooseX::Types later, avoid using characters that are invalid in perl -identifiers such as a space or period. +L later, avoid using characters that are invalid in +perl identifiers such as a space or period. =head2 Do not coerce Moose built-ins directly @@ -149,15 +164,15 @@ type. # very naughty! coerce 'ArrayRef' => from Str - => via { [ split /,/ ] }; + => via { [ split /,/ ] }; Instead, create a subtype and coerce that: - subtype 'My.ArrayRef' => as 'ArrayRef'; + subtype 'My::ArrayRef' => as 'ArrayRef'; - coerce 'My.ArrayRef' + coerce 'My::ArrayRef' => from 'Str' - => via { [ split /,/ ] }; + => via { [ split /,/ ] }; =head2 Do not coerce class names directly @@ -168,15 +183,15 @@ have magical side effects elsewhere: # also very naughty! coerce 'HTTP::Headers' => from 'HashRef' - => via { HTTP::Headers->new( %{$_} ) }; + => via { HTTP::Headers->new( %{$_} ) }; Instead, we can create an "empty" subtype for the coercion: - subtype 'My.HTTP::Headers' => as class_type('HTTP::Headers'); + subtype 'My::HTTP::Headers' => as class_type('HTTP::Headers'); - coerce 'My.HTTP::Headers' + coerce 'My::HTTP::Headers' => from 'HashRef' - => via { HTTP::Headers->new( %{$_} ) }; + => via { HTTP::Headers->new( %{$_} ) }; =head2 Use coercion instead of unions @@ -207,7 +222,7 @@ will be faster when immutabilized. Many of these practices also help get the most out of meta programming. If you used an overridden C to do type coercion by hand, rather than defining a real coercion, there is no introspectable -metadata. This sort of thing is particularly problematic MooseX +metadata. This sort of thing is particularly problematic for MooseX extensions which rely on introspection to do the right thing. =head1 AUTHOR