5 use Scalar::Util 'blessed';
10 our $VERSION = '1.15';
11 $VERSION = eval $VERSION;
12 our $AUTHORITY = 'cpan:STEVAN';
18 use Moose::Meta::Role;
19 use Moose::Util::TypeConstraints;
22 croak "Roles do not support 'extends' (you can use 'with' to specialize a role)";
26 Moose::Util::apply_all_roles( shift, @_ );
31 croak "Must specify at least one method" unless @_;
32 $meta->add_required_methods(@_);
37 croak "Must specify at least one role" unless @_;
38 $meta->add_excluded_roles(@_);
44 croak 'Usage: has \'name\' => ( key => value, ... )' if @_ == 1;
45 my %options = ( definition_context => Moose::Util::_caller_info(), @_ );
46 my $attrs = ( ref($name) eq 'ARRAY' ) ? $name : [ ($name) ];
47 $meta->add_attribute( $_, %options ) for @$attrs;
50 sub _add_method_modifier {
56 croak "Roles do not currently support "
58 . " references for $type method modifiers"
60 my $add_method = "add_${type}_method_modifier";
61 $meta->$add_method( $_, $code );
65 sub before { _add_method_modifier('before', @_) }
67 sub after { _add_method_modifier('after', @_) }
69 sub around { _add_method_modifier('around', @_) }
71 # see Moose.pm for discussion
73 return unless $Moose::SUPER_BODY;
74 $Moose::SUPER_BODY->(@Moose::SUPER_ARGS);
79 my ( $name, $code ) = @_;
80 $meta->add_override_method_modifier( $name, $code );
84 croak "Roles cannot support 'inner'";
88 croak "Roles cannot support 'augment'";
91 Moose::Exporter->setup_import_methods(
93 qw( with requires excludes has before after around override )
96 qw( extends super inner augment ),
98 \&Scalar::Util::blessed,
106 my $role = $args{for_class};
110 Moose->throw_error("Cannot call init_meta without specifying a for_class");
113 my $metaclass = $args{metaclass} || "Moose::Meta::Role";
114 my $meta_name = exists $args{meta_name} ? $args{meta_name} : 'meta';
116 Moose->throw_error("The Metaclass $metaclass must be a subclass of Moose::Meta::Role.")
117 unless $metaclass->isa('Moose::Meta::Role');
119 # make a subtype for each Moose role
120 role_type $role unless find_type_constraint($role);
123 if ( $meta = Class::MOP::get_metaclass_by_name($role) ) {
124 unless ( $meta->isa("Moose::Meta::Role") ) {
125 my $error_message = "$role already has a metaclass, but it does not inherit $metaclass ($meta).";
126 if ( $meta->isa('Moose::Meta::Class') ) {
127 Moose->throw_error($error_message . ' You cannot make the same thing a role and a class. Remove either Moose or Moose::Role.');
129 Moose->throw_error($error_message);
134 $meta = $metaclass->initialize($role);
137 if (defined $meta_name) {
138 # also check for inherited non moose 'meta' method?
139 my $existing = $meta->get_method($meta_name);
140 if ($existing && !$existing->isa('Class::MOP::Method::Meta')) {
141 Carp::cluck "Moose::Role is overwriting an existing method named "
142 . "$meta_name in role $role with a method "
143 . "which returns the class's metaclass. If this is "
144 . "actually what you want, you should remove the "
145 . "existing method, otherwise, you should rename or "
146 . "disable this generated method using the "
147 . "'-meta_name' option to 'use Moose::Role'.";
149 $meta->_add_meta_method($meta_name);
163 Moose::Role - The Moose Role
168 use Moose::Role; # automatically turns on strict and warnings
173 my ($self, $other) = @_;
174 !$self->equal($other);
177 # ... then in your classes
180 use Moose; # automatically turns on strict and warnings
185 my ($self, $other) = @_;
186 $self->as_float == $other->as_float;
191 The concept of roles is documented in L<Moose::Manual::Roles>. This document
192 serves as API documentation.
194 =head1 EXPORTED FUNCTIONS
196 Moose::Role currently supports all of the functions that L<Moose> exports, but
197 differs slightly in how some items are handled (see L</CAVEATS> below for
200 Moose::Role also offers two role-specific keyword exports:
204 =item B<requires (@method_names)>
206 Roles can require that certain methods are implemented by any class which
209 Note that attribute accessors also count as methods for the purposes
210 of satisfying the requirements of a role.
212 =item B<excludes (@role_names)>
214 Roles can C<exclude> other roles, in effect saying "I can never be combined
215 with these C<@role_names>". This is a feature which should not be used
222 Moose::Role offers a way to remove the keywords it exports, through the
223 C<unimport> method. You simply have to say C<no Moose::Role> at the bottom of
224 your code for this to work.
226 =head2 B<< Moose::Role->init_meta(for_class => $role, metaclass => $metaclass) >>
228 The C<init_meta> method sets up the metaclass object for the role
229 specified by C<for_class>. It also injects a a C<meta> accessor into
230 the role so you can get at this object.
232 The default metaclass is L<Moose::Meta::Role>. You can specify an
233 alternate metaclass with the C<metaclass> parameter.
237 When you use Moose::Role, you can specify which metaclass to use:
239 use Moose::Role -metaclass => 'My::Meta::Role';
241 You can also specify traits which will be applied to your role metaclass:
243 use Moose::Role -traits => 'My::Trait';
245 This is very similar to the attribute traits feature. When you do
246 this, your class's C<meta> object will have the specified traits
247 applied to it. See L<Moose/Metaclass and Trait Name Resolution> for more
250 =head1 APPLYING ROLES
252 In addition to being applied to a class using the 'with' syntax (see
253 L<Moose::Manual::Roles>) and using the L<Moose::Util> 'apply_all_roles'
254 method, roles may also be applied to an instance of a class using
255 L<Moose::Util> 'apply_all_roles' or the role's metaclass:
257 MyApp::Test::SomeRole->meta->apply( $instance );
259 Doing this creates a new, mutable, anonymous subclass, applies the role to that,
260 and reblesses. In a debugger, for example, you will see class names of the
261 form C< Class::MOP::Class::__ANON__::SERIAL::6 >, which means that doing a 'ref'
262 on your instance may not return what you expect. See L<Moose::Object> for 'DOES'.
264 Additional params may be added to the new instance by providing 'rebless_params'.
265 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.
301 Stevan Little E<lt>stevan@iinteractive.comE<gt>
303 Christian Hansen E<lt>chansen@cpan.orgE<gt>
305 =head1 COPYRIGHT AND LICENSE
307 Copyright 2006-2010 by Infinity Interactive, Inc.
309 L<http://www.iinteractive.com>
311 This library is free software; you can redistribute it and/or modify
312 it under the same terms as Perl itself.