B<Do not define a C<new()> method for your classes!>
-When you C<use Moose> in your class, you will become a subclass of
-L<Moose::Object>, which provides a C<new> method for you. If you
-follow our recommendations in L<Moose::Manual::BestPractices> and make
-your class immutable, then you actually get a class-specific C<new>
+When you C<use Moose> in your class, your class becomes a subclass of
+L<Moose::Object>. The L<Moose::Object> provides a C<new()> method for your
+class. If you follow our recommendations in L<Moose::Manual::BestPractices>
+and make your class immutable, then you actually get a class-specific C<new()>
method "inlined" in your class.
=head1 OBJECT CONSTRUCTION AND ATTRIBUTES
The C<BUILDARGS> method is called as a class method I<before> an
object is created. It will receive all of the arguments that were
-passed to C<new> I<as-is>, and is expected to return a hash
+passed to C<new()> I<as-is>, and is expected to return a hash
reference. This hash reference will be used to construct the object,
so it should contain keys matching your attributes' names (well,
C<init_arg>s).
accommodate this calling style:
around BUILDARGS => sub {
- my $orig = shift;
+ my $orig = shift;
my $class = shift;
- if ( @_ == 1 && ! ref $_[0] ) {
- return $class->$orig(ssn => $_[0]);
+ if ( @_ == 1 && !ref $_[0] ) {
+ return $class->$orig( ssn => $_[0] );
}
else {
return $class->$orig(@_);
}
};
-Note the call to C<< $class->$orig >>. This will call the default
-C<BUILDARGS> in L<Moose::Object>. This method handles distinguishing
-between a hash reference and a plain hash for you.
+Note the call to C<< $class->$orig >>. This will call the default C<BUILDARGS>
+in L<Moose::Object>. This method takes care of distinguishing between a hash
+reference and a plain hash for you.
=head2 BUILD
The C<BUILD> method is called I<after> an object is created. There are
-several ways to use a C<BUILD> method. One of the most common is to
+several reasons to use a C<BUILD> method. One of the most common is to
check that the object state is valid. While we can validate individual
attributes through the use of types, we can't validate the state of a
whole object that way.
=head3 BUILD and parent classes
-The interaction between multiple C<BUILD> methods in an inheritance
-hierarchy is different from normal Perl methods. B<You should never
-call C<< $self->SUPER::BUILD >>.>
+The interaction between multiple C<BUILD> methods in an inheritance hierarchy
+is different from normal Perl methods. B<You should never call C<<
+$self->SUPER::BUILD >>>, nor should you ever apply a method modifier to
+C<BUILD>.
Moose arranges to have all of the C<BUILD> methods in a hierarchy
called when an object is constructed, I<from parents to
Or an attribute:
- $meta->add_attribute( 'size' => { is => 'rw', isa => 'Int' } );
+ $meta->add_attribute( 'size' => ( is => 'rw', isa => 'Int' ) );
Obviously, this is much more cumbersome than using Perl syntax or
Moose sugar for defining methods and attributes, but this API allows
use Moose;
sub foo {
- print "foo\n";
+ print " foo\n";
}
before 'foo' => sub { print "about to call foo\n"; };
my $orig = shift;
my $self = shift;
- print "I'm around foo\n";
+ print " I'm around foo\n";
$self->$orig(@_);
- print "I'm still around foo\n";
+ print " I'm still around foo\n";
};
Now if I call C<< Example->new->foo >> I'll get the following output:
about to call foo
- I'm around foo
- foo
- I'm still around foo
+ I'm around foo
+ foo
+ I'm still around foo
just called foo
You probably could have figured that out from the names "before",
=head1 WHY USE THEM?
-Method modifiers have many uses. One very common use is in roles. This
-lets roles alter the behavior of methods in the classes that use
-them. See L<Moose::Manual::Roles> for more information about roles.
+Method modifiers have many uses. They are often used in roles to alter the
+behavior of methods in the classes that consume the role. See
+L<Moose::Manual::Roles> for more information about roles.
Since modifiers are mostly useful in roles, some of the examples below
are a bit artificial. They're intended to give you an idea of how
Note that the return values of both before and after modifiers are
ignored.
-An around modifier is a bit more powerful than either a before or
+An around modifier is more powerful than either a before or
after modifier. It can modify the arguments being passed to the
original method, and you can even decide to simply not call the
original method at all. You can also modify the return value with an
C<before>, C<after>, and C<around> can also modify multiple methods
at once. The simplest example of this is passing them as a list:
- before qw(foo bar baz) => sub {
+ before [qw(foo bar baz)] => sub {
warn "something is being called!";
};
either as a bare list, or as an arrayref. Note that the name of the
function being modified isn't passed in in any way; this syntax is
only intended for cases where the function being modified doesn't
-actually matter. If the function name does matter, something like:
+actually matter. If the function name does matter, use something like this:
for my $func (qw(foo bar baz)) {
before $func => sub {
};
}
-would be more appropriate.
-
In addition, you can specify a regular expression to indicate the
methods to wrap, like so:
This will match the regular expression against each method name
returned by L<Class::MOP::Class/get_method_list>, and add a modifier
-to each one that matches. The same caveats apply as above, regarding
-not being given the name of the method being modified. Using regular
+to each one that matches. The same caveats apply as above. Using regular
expressions to determine methods to wrap is quite a bit more powerful
than the previous alternatives, but it's also quite a bit more
dangerous. In particular, you should make sure to avoid wrapping
-methods with a special meaning to Moose or Perl, such as C<meta>,
+methods with a special meaning to Moose or Perl, such as C<meta>, C<new>,
C<BUILD>, C<DESTROY>, C<AUTOLOAD>, etc., as this could cause
unintended (and hard to debug) problems.
augment 'as_xml' => sub {
my $self = shift;
- my $xml = "<report>\n";
+ my $xml = " <report>\n";
$xml .= inner();
- $xml .= "</report>\n";
+ $xml .= " </report>\n";
return $xml;
};
When we call C<as_xml> on a Report object, we get something like this:
<document>
- <report>
- </report>
+ <report>
+ </report>
</document>
But we also called C<inner()> in C<Report>, so we can continue
augment 'as_xml' => sub {
my $self = shift;
- my $xml = '<income>' . $self->income . '</income>';
+ my $xml = ' <income>' . $self->income . '</income>';
$xml .= "\n";
- $xml .= '<expenses>' . $self->expenses . '</expenses>';
+ $xml .= ' <expenses>' . $self->expenses . '</expenses>';
$xml .= "\n";
$xml .= inner() || q{};
Now our report has some content:
<document>
- <report>
- <income>$10</income>
- <expenses>$8</expenses>
- </report>
+ <report>
+ <income>$10</income>
+ <expenses>$8</expenses>
+ </report>
</document>
What makes this combination of C<augment> and C<inner()> special is
specific) to child (most specific). This inverts the normal
inheritance pattern.
-Note that in C<Report::IncomeAndExpenses> we call C<inner()> again. If
-the object is an instance of C<Report::IncomeAndExpenses> then this
-call is a no-op, and just returns false.
+Note that in C<Report::IncomeAndExpenses> we call C<inner()> again. If the
+object is an instance of C<Report::IncomeAndExpenses> then this call is a
+no-op, and just returns false. It's a good idea to always call C<inner()> to
+allow for future subclassing.
=head1 OVERRIDE AND SUPER
=head1 WHAT IS A ROLE?
-A role is something that classes do. Usually, a role encapsulates some
-piece of behavior or state that can be shared between classes. It is
-important to understand that I<roles are not classes>. You cannot
-inherit from a role, and a role cannot be instantiated. We sometimes
-say that roles are I<consumed>, either by classes or other roles.
+A role encapsulates some piece of behavior or state that can be shared between
+classes. Is something that classes I<do>. It is important to understand that
+I<roles are not classes>. You cannot inherit from a role, and a role cannot be
+instantiated. We sometimes say that roles are I<consumed>, either by classes
+or other roles.
Instead, a role is I<composed> into a class. In practical terms, this
-means that all of the methods and attributes defined in a role are
+means that all of the methods, method modifiers, and attributes defined in a role are
added directly to (we sometimes say "flattened into") the class that
consumes the role. These attributes and methods then appear as if they
were defined in the class itself. A subclass of the consuming class
interface.
Note that attribute accessors also count as methods for the
-purposes of satisfying the requirements of a role.
+purposes of satisfying the requirements of a role.
=head1 A SIMPLE ROLE
=head2 Required Attributes
-As mentioned before, a role requirement may also be satisfied by an
-attribute accessor. But any C<has> functions, which will generate
-accessors that satisfy the role requirement, must be placed
-I<before> the C<with> function that composes the role.
+As mentioned before, a role's required method may also be satisfied by an
+attribute accessor. However, the call to C<has> which defines an attribute
+happens at runtime. This means that you must define the attribute I<before>
+consuming the role, or else the role will not see the generated accessor.
package Breakable;
use Moose;
- has 'stress' => (
+ has 'stress' => (
is => 'rw',
isa => 'Int',
);
excludes 'BreakDancer';
-=head1 APPLYING ROLES
-
-A role can be applied to a class or an instance in other ways besides
-using the 'with' syntax.
-
-To apply a role to a class, use L<Moose::Util> and the 'apply_all_roles'
-function. If you apply the role to a class, it will affect all objects of that
-class. You can't apply a role to a class if it has been made immutable. In
-some circumstances it may make sense to make the class mutable, apply the role,
-then make the class immutable again.
-
- use Moose::Util;
- ...
- my $class = 'MyApp::Test';
- $class->meta->make_mutable;
- Moose::Util::apply_all_roles($class->meta, ('MyApp::SomeRole'));
- $class->meta->make_immutable;
-
-Do not apply roles to classes that have immutable subclasses, since that
-will invalidate the metadata of the subclasses.
-
-If you want the role to be applied only to a particular instance and not to the
-class, you can apply the roles to the instance instead of the class's meta:
-
- Moose::Util::apply_all_roles($instance, ('MyApp::SomeRole'));
-
-Or you can use the role's meta object:
-
- MyApp::SomeRole->meta->apply($instance);
-
-The mutable/immutable state is not relevant to roles applied to instances.
-See L<Moose::Role> and L<Moose::Util> for more details and
-L<Moose::Cookbook::Roles::Recipe3> for a more developed example.
-
=head1 ADDING A ROLE TO AN OBJECT INSTANCE
-Sometimes you may want to add a role to an object instance, rather than to a
-class. For example, you may want to add debug tracing to one instance of an
-object while debugging a particular bug. Another use case might be to
-dynamically change objects based on a user's configuration, as a plugin
-system.
+You may want to add a role to an object instance, rather than to a class. For
+example, you may want to add debug tracing to one instance of an object while
+debugging a particular bug. Another use case might be to dynamically change
+objects based on a user's configuration, as a plugin system.
-The best way to do this is to use the C<apply_all_roles> function from
+The best way to do this is to use the C<apply_all_roles()> function from
L<Moose::Util>:
use Moose::Util qw( apply_all_roles );
module.
Moose's type system is based on a combination of Perl 5's own
-I<implicit> types and some Perl 6 concepts. You can easily create your
+I<implicit> types and some Perl 6 concepts. You can create your
own subtypes with custom constraints, making it easy to express any
sort of validation.
Types have names, and you can re-use them by name, making it easy to
share types throughout a large application.
-Let us be clear that is not a "real" type system. Moose does not
-magically make Perl start associating types with variables. This is
-just an advanced parameter checking system which allows you to
-associate a name with a constraint.
+However, this is not a "real" type system. Moose does not magically make Perl
+start associating types with variables. This is just an advanced parameter
+checking system which allows you to associate a name with a constraint.
That said, it's still pretty damn useful, and we think it's one of the
things that makes Moose both fun and powerful. Taking advantage of the
Defined
Value
Str
- Num
- Int
- ClassName
- RoleName
+ Num
+ Int
+ ClassName
+ RoleName
Ref
ScalarRef[`a]
ArrayRef[`a]
CodeRef
RegexpRef
GlobRef
- FileHandle
+ FileHandle
Object
In practice, the only difference between C<Any> and C<Item> is
=over 4
-=item C<Bool> accepts C<1> for true, and any value that perl treats as false for false.
+=item
-=item C<Maybe[`a]> accepts either C<`a> or C<undef>.
+C<Bool> accepts C<1> for true, and undef, 0, or the empty string as false.
-=item C<Num> accepts anything that perl thinks looks like a number (see L<Scalar::Util/looks_like_number>).
+=item
-=item C<ClassName> and C<RoleName> accept strings that are either the name of a class or the name of a role. The class/role must be loaded beforehand for this to succeed.
+C<Maybe[`a]> accepts either C<`a> or C<undef>.
-=item C<FileHandle> accepts either an object of type L<IO::Handle> or a builtin perl filehandle (see L<Scalar::Util/openhandle>).
+=item
-=item C<Object> accepts any blessed reference.
+C<Num> accepts anything that perl thinks looks like a number (see L<Scalar::Util/looks_like_number>).
+
+=item
+
+C<ClassName> and C<RoleName> accept strings that are either the name of a class or the name of a role. The class/role must already be loaded when the constraint is checked.
+
+=item
+
+C<FileHandle> accepts either an L<IO::Handle> object or a builtin perl filehandle (see L<Scalar::Util/openhandle>).
+
+=item
+
+C<Object> accepts any blessed reference.
=back
Note that the sugar functions for working with types are all exported
by L<Moose::Util::TypeConstraints>.
-=head2 Creating a new type (that isn't a subtype)
-
-You can also create new top-level types:
-
- type 'FourCharacters' => where { defined $_ && length $_ == 4 };
-
-In practice, this example is more or less the same as subtyping
-C<Str>, except you have to check definedness yourself.
-
-It's hard to find a case where you wouldn't want to subtype a very
-broad type like C<Defined>, C<Ref> or C<Object>.
-
-Defining a new top-level type is conceptually the same as subtyping
-C<Item>.
-
=head1 TYPE NAMES
Type names are global throughout the current Perl
package, C<MyApp::Types>, which can be loaded by other classes in your
application.
-Once you're doing this, you should almost certainly look at the
-L<MooseX::Types> module. This module makes it easy to create a "type library"
-module, which can export your types as perl constants.
+However, before you do this, you should look at the L<MooseX::Types>
+module. This module makes it easy to create a "type library" module, which can
+export your types as perl constants.
has 'counter' => (is => 'rw', isa => PositiveInt);
=head1 COERCION
-One of the most powerful features of Moose's type system is its
-coercions. A coercion is a way to convert from one type to another.
+A coercion lets you tell Moose to automatically convert one type to another.
subtype 'ArrayRefOfInts'
=> as 'ArrayRef[Int]';
=> from 'Int'
=> via { [ $_ ] };
-You'll note that we had to create a subtype rather than coercing
-C<ArrayRef[Int]> directly. This is just a quirk of how Moose
-works.
+You'll note that we created a subtype rather than coercing C<ArrayRef[Int]>
+directly. It's a bad idea to add coercions to the raw built in
+types.
+
+Coercions are global, just like type names, so a coercion applied to a built
+in type is seen by all modules using Moose types. This is I<another> reason
+why it is good to namespace your types.
-Coercions, like type names, are global. This is I<another> reason why
-it is good to namespace your types. Moose will I<never> try to coerce
-a value unless you explicitly ask for it. This is done by setting the
-C<coerce> attribute option to a true value:
+Moose will I<never> try to coerce a value unless you explicitly ask for
+it. This is done by setting the C<coerce> attribute option to a true value:
package Foo;
Now Moose will coerce the hex numbers to integers.
-However, Moose does not attempt to chain coercions, so it will not
+Moose does not attempt to chain coercions, so it will not
coerce a single hex number. To do that, we need to define a separate
coercion:
my $self = shift;
my $fh = $self->handle();
- print $fh @_;
+ print {$fh} @_;
}
Now we can define a coercion from C<FileHandle> to our wrapper class:
type, or as the value for an attribute's C<isa> option:
has 'size' => (
- is => 'ro',
- isa => subtype('Int' => where { $_ > 0 }),
+ is => 'ro',
+ isa => subtype( 'Int' => where { $_ > 0 } ),
);
This is handy when you want to create a one-off type and don't want to
L<MooseX::Method::Signatures>, which gives you a full-blown C<method>
keyword.
- method morning (Str $name) {
+ method morning ( Str $name ) {
$self->say("Good morning ${name}!");
}
order problems. In particular, you may want to use a class's type
constraint before that type has been defined.
-We have several recommendations for ameliorating this problem. First,
-define I<all> of your custom types in one module,
-C<MyApp::Types>. Second, load this module in all of your other
-modules.
+In order to ameliorate this problem, we recommend defining I<all> of your
+custom types in one module, C<MyApp::Types>, and then loading this module in
+all of your other modules.
=head1 AUTHOR