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<coercions> (See the L<Moose::Cookbook::Recipe5>
-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<around> method modifier on C<new> 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<new> and/or work around your C<new> to get to the
-version from L<Moose::Object>.
-
-The last approach is to use the standard Perl technique of calling
-the C<SUPER::new> within your own custom version of C<new>. This,
-of course, brings with it all the issues of the C<around> solution
-as well as any issues C<SUPER::> might add.
-
-In short, try to use C<BUILD> and coercions, they are your best
-bets.
+To change the parameter processing as a whole, you can use
+the C<BUILDARGS> 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<coercions>
+(See the L<Moose::Cookbook::Basics::Recipe5> 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?
-Moose provides its own constructor, but it does it by making all
-Moose-based classes inherit from L<Moose::Object>. When inheriting
-from a non-Moose class, the inheritance chain to L<Moose::Object>
-is broken. The simplest way to fix this is to simply explicitly
-inherit from L<Moose::Object> yourself. However, this does not
-always fix the issue of a constructor. Here is a basic example of
-how this can be worked around:
+Usually the correct approach to subclassing a non Moose class is
+delegation. Moose makes this easy using the C<handles> keyword,
+coercions, and C<lazy_build>, so subclassing is often not the
+ideal route.
+
+That said, the default Moose constructor is inherited from
+L<Moose::Object>. When inheriting from a non-Moose class, the
+inheritance chain to L<Moose::Object> is broken. The simplest way
+to fix this is to simply explicitly inherit from L<Moose::Object>
+yourself.
+
+However, this does not always fix the issue of actually calling the Moose
+constructor. Fortunately L<Class::MOP::Class/new_object>, the low level
+constructor, accepts the special C<__INSTANCE__> parameter, allowing you to
+instantiate your Moose attributes:
package My::HTML::Template;
use Moose;
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).
+HASH refs).
+
+Note that this doesn't call C<BUILDALL> automatically, you must do that
+yourself.
Other techniques can be used as well, such as creating the object
using C<Moose::Object::new>, but calling the inherited non-Moose
is => 'rw',
);
-And have Moose create seperate C<get_bar> and C<set_bar> methods
+And have Moose create separate C<get_bar> and C<set_bar> methods
instead of a single C<bar> method.
NOTE: This B<cannot> be set globally in Moose, as that would break
in the C<via> block.
For a more comprehensive example of using coercions, see the
-L<Moose::Cookbook::Recipe5>.
+L<Moose::Cookbook::Basics::Recipe5>.
If you need to deflate your attribute, the current best practice is to
add an C<around> modifier to your accessor. Here is some example code:
See L<Moose::Cookbook::WTF> and specifically the B<How come BUILD
is not called for my composed roles?> question in the B<Roles> section.
+=head3 What are Traits, and how are they different to 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<Role> is usually composed into a I<class> at
+compile time, whereas a I<Trait> is usually composed into an instance
+of a class at runtime to add or modify the behavior of B<just that
+instance>.
+
+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 E<lt>stevan@iinteractive.comE<gt>
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