=head2 Read-write vs. read-only
-The options passed to C<has> define the properties of the
-attribute. There are many options, but in the simplest form you just
-need to set C<is>, which can be either C<rw> (read-write) or C<ro>
-(read-only). When an attribute is C<rw>, you can change it by passing
-a value to its accessor. When an attribute is C<ro>, you may only read
-the current value of the attribute.
+The options passed to C<has> define the properties of the attribute. There are
+many options, but in the simplest form you just need to set C<is>, which can
+be either C<ro> (read-only) or C<rw> (read-write). When an attribute is C<rw>,
+you can change it by passing a value to its accessor. When an attribute is
+C<ro>, you may only read the current value of the attribute.
In fact, you could even omit C<is>, but that gives you an attribute
that has no accessor. This can be useful with other attribute options,
method on the object, with no additional parameters:
has 'size' => (
- is => 'ro',
+ is => 'ro',
default => sub {
my $self = shift;
- return $self->height > 200 ? 'big' : 'average';
+ return $self->height > 200 ? 'large' : 'average';
},
);
attribute C<lazy>. Laziness is covered in the next section.
If you want to use a reference of any sort as the default value, you
-must return it from a subroutine. This is necessary because otherwise
-Perl would instantiate the reference exactly once, and it would be
-shared by all objects:
+must return it from a subroutine.
+
+ has 'mapping' => (
+ is => 'ro',
+ default => sub { {} },
+ );
+
+This is necessary because otherwise Perl would instantiate the reference
+exactly once, and it would be shared by all objects:
has 'mapping' => (
is => 'ro',
If Moose allowed this then the default mapping attribute could easily
end up shared across many objects. Instead, wrap it in a subroutine
-reference:
-
- has 'mapping' => (
- is => 'ro',
- default => sub { {} }, # right!
- );
+reference as we saw above.
This is a bit awkward, but it's just the way Perl works.
-As an alternative to using a subroutine reference, you can instead
-supply a C<builder> method for your attribute:
+As an alternative to using a subroutine reference, you can supply a C<builder>
+method for your attribute:
has 'size' => (
is => 'ro',
return ( 'small', 'medium', 'large' )[ int( rand 3 ) ];
}
-This has several advantages. First, it moves a chunk of code to its
-own named method, which improves readability and code
-organization.
+This has several advantages. First, it moves a chunk of code to its own named
+method, which improves readability and code organization. Second, because this
+is a I<named> method, it can be subclassed or provided by a role.
We strongly recommend that you use a C<builder> instead of a
C<default> for anything beyond the most trivial default.
sub _build_size { return 'small' }
-=head3 Builders can be composed from roles
+=head3 Builders work well with roles
Because builders are called by name, they work well with roles. For
example, a role could provide an attribute but require that the
Roles are covered in L<Moose::Manual::Roles>.
-=head2 Laziness and C<lazy_build>
+=head2 Laziness
Moose lets you defer attribute population by making an attribute
C<lazy>:
We recommend that you make any attribute with a builder or non-trivial
default C<lazy> as a matter of course.
-To facilitate this, you can simply specify the C<lazy_build> attribute
-option. This bundles up a number of options together:
-
- has 'size' => (
- is => 'ro',
- lazy_build => 1,
- );
-
-This is the same as specifying all of these options:
-
- has 'size' => (
- is => 'ro',
- lazy => 1,
- builder => '_build_size',
- clearer => 'clear_size',
- predicate => 'has_size',
- );
-
-If your attribute name starts with an underscore (C<_>), then the clearer
-and predicate will as well:
-
- has '_size' => (
- is => 'ro',
- lazy_build => 1,
- );
-
-becomes:
-
- has '_size' => (
- is => 'ro',
- lazy => 1,
- builder => '_build__size',
- clearer => '_clear_size',
- predicate => '_has_size',
- );
-
-Note the doubled underscore in the builder name. Internally, Moose
-simply prepends the attribute name with "_build_" to come up with the
-builder name.
-
-If you don't like the names that C<lazy_build> generates, you can
-always provide your own:
-
- has 'size' => (
- is => 'ro',
- lazy_build => 1,
- clearer => '_clear_size',
- );
-
-Options that you explicitly provide are always used in favor of
-Moose's internal defaults.
-
=head2 Constructor parameters (C<init_arg>)
By default, each attribute can be passed by name to the class's
the constructor parameter. You may also want to make an attribute
unsettable via the constructor.
-Both of these goals can be accomplished with the C<init_arg> option:
+You can do either of these things with the C<init_arg> option:
has 'bigness' => (
is => 'ro',
the constructor. This is particularly handy for private attributes:
has '_genetic_code' => (
- is => 'ro',
- lazy_build => 1,
- init_arg => undef,
+ is => 'ro',
+ lazy => 1,
+ builder => '_build_genetic_code',
+ init_arg => undef,
);
By setting the C<init_arg> to C<undef>, we make it impossible to set
called as a method on the object, and receives the new and old values as
its arguments. If the attribute had not previously been set at all,
then only the new value is passed. This lets you distinguish between
-the case where the attribute had no value versus when it was C<undef>.
+the case where the attribute had no value versus when the old value was C<undef>.
This differs from an C<after> method modifier in two ways. First, a
trigger is only called when the attribute is set, as opposed to
See L<Moose::Manual::Delegation> for documentation on how to set up
delegation methods.
-=head2 Metaclass and traits
-
-One of Moose's best features is that it can be extended in all sorts
-of ways through the use of custom metaclasses and metaclass traits.
-
-When declaring an attribute, you can declare a metaclass or a set of
-traits for the attribute:
-
- has 'mapping' => (
- metaclass => 'Hash',
- is => 'ro',
- default => sub { {} },
- );
+=head2 Attribute traits and metaclasses
-In this case, the metaclass C<Hash> really refers to
-L<Moose::Meta::Attribute::Native::Trait::Hash>. Moose also provides
-native traits for L<Number|Moose::Meta::Attribute::Native::Trait::Number>,
-L<Counter|Moose::Meta::Attribute::Native::Trait::Counter>,
-L<String|Moose::Meta::Attribute::Native::Trait::String>,
-L<Bool|Moose::Meta::Attribute::Native::Trait::Bool>, and
-L<Array|Moose::Meta::Attribute::Native::Trait::Array>.
+One of Moose's best features is that it can be extended in all sorts of ways
+through the use of metaclass traits and custom metaclasses.
-You can also apply one or more traits to an attribute:
+You can apply one or more traits to an attribute:
use MooseX::MetaDescription;
some examples. You can also write your own metaclasses and traits. See
the "Meta" and "Extending" recipes in L<Moose::Cookbook> for examples.
-=head1 ATTRIBUTE INHERITANCE
-
-By default, a child inherits all of its parent class(es)' attributes
-as-is. However, you can explicitly change some aspects of the
-inherited attribute in the child class.
+=head2 Native Traits
-The options that can be overridden in a subclass are:
+The Native Traits feature allows standard Perl data structures to be treated
+as if they were objects for the purposes of delegation.
-=over 4
+For example, we can pretend that an array reference has methods like
+C<push()>, C<shift()>, C<map()>, C<count()>, and more.
-=item * default
+ has 'options' => (
+ traits => ['Array'],
+ is => 'ro',
+ isa => 'ArrayRef[Str]',
+ default => sub { [] },
+ handles => {
+ all_options => 'elements',
+ add_option => 'push',
+ map_options => 'map',
+ option_count => 'count',
+ sorted_options => 'sort',
+ },
+ );
-=item * coerce
+Moose includes the following native traits:
-=item * required
+=over 4
-=item * documentation
+=item * L<Array|Moose::Meta::Attribute::Native::Trait::Array>
-=item * lazy
+=item * L<Bool|Moose::Meta::Attribute::Native::Trait::Bool>
-=item * isa
+=item * L<Code|Moose::Meta::Attribute::Native::Trait::Code>
-=item * handles
+=item * L<Counter|Moose::Meta::Attribute::Native::Trait::Counter>
-=item * builder
+=item * L<Hash|Moose::Meta::Attribute::Native::Trait::Hash>
-=item * metaclass
+=item * L<Number|Moose::Meta::Attribute::Native::Trait::Number>
-=item * traits
+=item * L<String|Moose::Meta::Attribute::Native::Trait::String>
=back
+=head1 ATTRIBUTE INHERITANCE
+
+By default, a child inherits all of its parent class(es)' attributes
+as-is. However, you can change most aspects of the inherited attribute in the
+child class. You cannot change any of its associated method names (reader,
+writer, predicate, etc).
+
To override an attribute, you simply prepend its name with a plus sign
(C<+>):
=head2 Initializer
-Moose provides an attribute option called C<initializer>. This is
-similar to C<builder>, except that it is I<only> called during object
-construction.
-
-This option is inherited from L<Class::MOP>, but we recommend that you
-use a C<builder> (which is Moose-only) instead.
+Moose provides an attribute option called C<initializer>. This is called when
+the attribute's value is being set in the constructor, and lets you change the
+value before it is set.
=head1 AUTHOR
There's actually a lot going on here under the hood, so let's step
through it.
-When you load L<Moose>, a bunch of sugar functions are exported into
-your class. These include things like C<extends>, C<has>, C<with>, and
-more. These functions are what you use to define your class. For
-example, you might define an attribute ...
+When you load L<Moose>, a bunch of sugar functions are exported into your
+class, such as C<extends>, C<has>, C<with>, and more. These functions are what
+you use to define your class. For example, you might define an attribute ...
package Person;
Attributes are described in the L<Moose::Manual::Attributes>
documentation.
-Loading Moose also enables C<strict> and C<warnings> pragmas in your
+Loading Moose also enables the C<strict> and C<warnings> pragmas in your
class.
When you load Moose, your class will become a subclass of
initializing attributes manually, either in the parent's constructor,
or in your subclass, and you will lose a lot of Moose magic.
-=head1 NO MOOSE
+See the L<MooseX::NonMoose> module on CPAN if you're interested in extending
+non-Moose parent classes with Moose child classes.
-Moose also allows you to remove its sugar functions from your class's
-namespace. We recommend that you take advantage of this feature, since
-it just makes your classes "cleaner". You can do this by simply adding
-C<no Moose> at the end of your module file.
+=head1 CLEANING UP MOOSE DROPPINGS
+
+Moose exports a number of functions into your class. It's a good idea to
+remove these sugar functions from your class's namespace, so that C<<
+Person->can('has') >> will no longer return true.
+
+There are several ways to do this. We recommend using L<namespace::autoclean>,
+a CPAN module. Not only will it remove Moose exports, it will also remove
+any other exports.
package Person;
+ use namespace::autoclean;
+
use Moose;
- has 'ssn' => ( is => 'rw' );
+If you absolutely can't use a CPAN module (but can use Moose?), you can write
+C<no Moose> at the end of your class. This will remove any Moose exports in
+your class.
- no Moose;
+ package Person;
-This deletes Moose's sugar functions from your class's namespace, so
-that C<< Person->can('has') >> will no longer return true.
+ use Moose;
-A more generic way to unimport not only L<Moose>'s exports but also
-those from type libraries and other modules is to use
-L<namespace::clean> or L<namespace::autoclean>.
+ has 'ssn' => ( is => 'rw' );
+
+ no Moose;
=head1 MAKING IT FASTER
Moose has a feature called "immutabilization" that you can use to
-greatly speed up your classes at runtime. However, using it does incur
+greatly speed up your classes at runtime. However, using it incurs
a cost when your class is first being loaded. When you make your class
immutable you tell Moose that you will not be changing it in the
future. You will not be adding any more attributes, methods, roles, etc.
In the past, you may not have thought too much about the difference
between packages and classes, attributes and methods, constructors and
-methods, etc. With Moose, these are all conceptually separate things,
-even though under the hood they're implemented with plain old Perl.
+methods, etc. With Moose, these are all conceptually separate,
+though under the hood they're implemented with plain old Perl.
Our meta-object protocol (aka MOP) provides well-defined introspection
features for each of those concepts, and Moose in turn provides
Attributes I<are not> methods, but defining them causes various
accessor methods to be created. At a minimum, a normal attribute will
-always have a reader accessor method. Many attributes also have other
-methods, such as a writer method, clearer method, and predicate method
+have a reader accessor method. Many attributes have other
+methods, such as a writer method, a clearer method, or a predicate method
("has it been set?").
An attribute may also define B<delegations>, which will create
sub login { ... }
-=head2 Roles
+=head2 Role
A role is something that a class I<does>. We also say that classes
I<consume> roles. For example, a Machine class might do the Breakable
A role I<has> zero or more B<required methods>.
-A required method is not implemented by the role. Required methods say
-"to use this Role you must implement this method".
+A required method is not implemented by the role. Required methods are a way
+for the role to declare "to use this role you must implement this method".
A role I<has> zero or more B<excluded roles>.
=head2 Type
-Moose also comes with a (miniature) type system. This allows you to
-define types for attributes. Moose has a set of built-in types based
-on what Perl provides, such as C<Str>, C<Num>, C<Bool>, C<HashRef>, etc.
+Moose also comes with a (miniature) type system. This allows you to define
+types for attributes. Moose has a set of built-in types based on the types
+Perl provides in its core, such as C<Str>, C<Num>, C<Bool>, C<HashRef>, etc.
In addition, every class name in your application can also be used as
a type name.
-Finally, you can define your own types, either as subtypes or entirely
-new types, with their own constraints. For example, you could define a
-type C<PosInt>, a subtype of C<Int> which only allows positive numbers.
+Finally, you can define your own types with their own constraints. For
+example, you could define a C<PosInt> type, a subtype of C<Int> which only
+allows positive numbers.
=head2 Delegation
-Moose attributes provide declarative syntax for defining
-delegations. A delegation is a method which calls some method on an
-attribute to do its real work.
+Moose attributes provide declarative syntax for defining delegations. A
+delegation is a method which in turn calls some method on an attribute to do
+its real work.
=head2 Constructor
Hand-written parameter checking in your C<new()> method and accessors.
With Moose, you define types declaratively, and then use them by name
-in your attributes.
+with your attributes.
=item * Delegation
=head1 META WHAT?
-A metaclass is a class that describes classes. With Moose, every class
-you define gets a C<meta()> method. It returns a L<Moose::Meta::Class>
-object, which has an introspection API that can tell you about the
-class it represents.
+A metaclass is a class that describes classes. With Moose, every class you
+define gets a C<meta()> method. The C<meta()> method returns a
+L<Moose::Meta::Class> object, which has an introspection API that can tell you
+about the class it represents.
my $meta = User->meta();
After that, check out the Role recipes. If you're really curious, go
on and read the Meta and Extending recipes, but those are mostly there
-for people who want to be Moose wizards and change how Moose works.
+for people who want to be Moose wizards and extend Moose itself.
=head1 AUTHOR