5 use Scalar::Util 'blessed';
14 use Moose::Meta::Role;
15 use Moose::Util::TypeConstraints;
18 croak "Roles do not support 'extends' (you can use 'with' to specialize a role)";
22 Moose::Util::apply_all_roles( shift, @_ );
27 croak "Must specify at least one method" unless @_;
28 $meta->add_required_methods(@_);
33 croak "Must specify at least one role" unless @_;
34 $meta->add_excluded_roles(@_);
40 croak 'Usage: has \'name\' => ( key => value, ... )' if @_ == 1;
41 my %options = ( definition_context => Moose::Util::_caller_info(), @_ );
42 my $attrs = ( ref($name) eq 'ARRAY' ) ? $name : [ ($name) ];
43 $meta->add_attribute( $_, %options ) for @$attrs;
46 sub _add_method_modifier {
50 if ( ref($_[0]) eq 'Regexp' ) {
51 croak "Roles do not currently support regex "
52 . " references for $type method modifiers";
55 Moose::Util::add_method_modifier($meta, $type, \@_);
58 sub before { _add_method_modifier('before', @_) }
60 sub after { _add_method_modifier('after', @_) }
62 sub around { _add_method_modifier('around', @_) }
64 # see Moose.pm for discussion
66 return unless $Moose::SUPER_BODY;
67 $Moose::SUPER_BODY->(@Moose::SUPER_ARGS);
72 my ( $name, $code ) = @_;
73 $meta->add_override_method_modifier( $name, $code );
77 croak "Roles cannot support 'inner'";
81 croak "Roles cannot support 'augment'";
84 Moose::Exporter->setup_import_methods(
86 qw( with requires excludes has before after around override )
89 qw( extends super inner augment ),
91 \&Scalar::Util::blessed,
99 my $role = $args{for_class};
103 Moose->throw_error("Cannot call init_meta without specifying a for_class");
106 my $metaclass = $args{metaclass} || "Moose::Meta::Role";
107 my $meta_name = exists $args{meta_name} ? $args{meta_name} : 'meta';
109 Moose->throw_error("The Metaclass $metaclass must be loaded. (Perhaps you forgot to 'use $metaclass'?)")
110 unless Class::MOP::is_class_loaded($metaclass);
112 Moose->throw_error("The Metaclass $metaclass must be a subclass of Moose::Meta::Role.")
113 unless $metaclass->isa('Moose::Meta::Role');
115 # make a subtype for each Moose role
116 role_type $role unless find_type_constraint($role);
119 if ( $meta = Class::MOP::get_metaclass_by_name($role) ) {
120 unless ( $meta->isa("Moose::Meta::Role") ) {
121 my $error_message = "$role already has a metaclass, but it does not inherit $metaclass ($meta).";
122 if ( $meta->isa('Moose::Meta::Class') ) {
123 Moose->throw_error($error_message . ' You cannot make the same thing a role and a class. Remove either Moose or Moose::Role.');
125 Moose->throw_error($error_message);
130 $meta = $metaclass->initialize($role);
133 if (defined $meta_name) {
134 # also check for inherited non moose 'meta' method?
135 my $existing = $meta->get_method($meta_name);
136 if ($existing && !$existing->isa('Class::MOP::Method::Meta')) {
137 Carp::cluck "Moose::Role is overwriting an existing method named "
138 . "$meta_name in role $role with a method "
139 . "which returns the class's metaclass. If this is "
140 . "actually what you want, you should remove the "
141 . "existing method, otherwise, you should rename or "
142 . "disable this generated method using the "
143 . "'-meta_name' option to 'use Moose::Role'.";
145 $meta->_add_meta_method($meta_name);
153 # ABSTRACT: The Moose Role
162 use Moose::Role; # automatically turns on strict and warnings
167 my ($self, $other) = @_;
168 !$self->equal($other);
171 # ... then in your classes
174 use Moose; # automatically turns on strict and warnings
179 my ($self, $other) = @_;
180 $self->as_float == $other->as_float;
196 my $currency1 = Currency->new(...);
197 my $currency2 = Currency->new(...);
198 Comparator->new(compare_to => $currency1)->equal($currency2);
202 The concept of roles is documented in L<Moose::Manual::Roles>. This document
203 serves as API documentation.
205 =head1 EXPORTED FUNCTIONS
207 Moose::Role currently supports all of the functions that L<Moose> exports, but
208 differs slightly in how some items are handled (see L</CAVEATS> below for
211 Moose::Role also offers two role-specific keyword exports:
215 =item B<requires (@method_names)>
217 Roles can require that certain methods are implemented by any class which
220 Note that attribute accessors also count as methods for the purposes
221 of satisfying the requirements of a role.
223 =item B<excludes (@role_names)>
225 Roles can C<exclude> other roles, in effect saying "I can never be combined
226 with these C<@role_names>". This is a feature which should not be used
233 Moose::Role offers a way to remove the keywords it exports, through the
234 C<unimport> method. You simply have to say C<no Moose::Role> at the bottom of
235 your code for this to work.
239 When you use Moose::Role, you can specify traits which will be applied to your
242 use Moose::Role -traits => 'My::Trait';
244 This is very similar to the attribute traits feature. When you do
245 this, your class's C<meta> object will have the specified traits
246 applied to it. See L<Moose/Metaclass and Trait Name Resolution> for more
249 =head1 APPLYING ROLES
251 In addition to being applied to a class using the 'with' syntax (see
252 L<Moose::Manual::Roles>) and using the L<Moose::Util> 'apply_all_roles'
253 method, roles may also be applied to an instance of a class using
254 L<Moose::Util> 'apply_all_roles' or the role's metaclass:
256 MyApp::Test::SomeRole->meta->apply( $instance );
258 Doing this creates a new, mutable, anonymous subclass, applies the role to that,
259 and reblesses. In a debugger, for example, you will see class names of the
260 form C< Moose::Meta::Class::__ANON__::SERIAL::6 >, which means that doing a
261 'ref' on your instance may not return what you expect. See L<Moose::Object> for
264 Additional params may be added to the new instance by providing
265 'rebless_params'. See L<Moose::Meta::Role::Application::ToInstance>.
269 Role support has only a few caveats:
275 Roles cannot use the C<extends> keyword; it will throw an exception for now.
276 The same is true of the C<augment> and C<inner> keywords (not sure those
277 really make sense for roles). All other Moose keywords will be I<deferred>
278 so that they can be applied to the consuming class.
282 Role composition does its best to B<not> be order-sensitive when it comes to
283 conflict resolution and requirements detection. However, it is order-sensitive
284 when it comes to method modifiers. All before/around/after modifiers are
285 included whenever a role is composed into a class, and then applied in the order
286 in which the roles are used. This also means that there is no conflict for
287 before/around/after modifiers.
289 In most cases, this will be a non-issue; however, it is something to keep in
290 mind when using method modifiers in a role. You should never assume any
297 See L<Moose/BUGS> for details on reporting bugs.