5 use Scalar::Util 'blessed';
10 our $VERSION = '1.14';
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";
115 Moose->throw_error("The Metaclass $metaclass must be a subclass of Moose::Meta::Role.")
116 unless $metaclass->isa('Moose::Meta::Role');
118 # make a subtype for each Moose role
119 role_type $role unless find_type_constraint($role);
122 if ( $meta = Class::MOP::get_metaclass_by_name($role) ) {
123 unless ( $meta->isa("Moose::Meta::Role") ) {
124 my $error_message = "$role already has a metaclass, but it does not inherit $metaclass ($meta).";
125 if ( $meta->isa('Moose::Meta::Class') ) {
126 Moose->throw_error($error_message . ' You cannot make the same thing a role and a class. Remove either Moose or Moose::Role.');
128 Moose->throw_error($error_message);
133 $meta = $metaclass->initialize($role);
136 unless ( $meta->has_method("meta") ) { # don't overwrite
137 # also check for inherited non moose 'meta' method?
138 # FIXME also skip this if the user requested by passing an option
139 $meta->_add_meta_method;
153 Moose::Role - The Moose Role
158 use Moose::Role; # automatically turns on strict and warnings
163 my ($self, $other) = @_;
164 !$self->equal($other);
167 # ... then in your classes
170 use Moose; # automatically turns on strict and warnings
175 my ($self, $other) = @_;
176 $self->as_float == $other->as_float;
181 The concept of roles is documented in L<Moose::Manual::Roles>. This document
182 serves as API documentation.
184 =head1 EXPORTED FUNCTIONS
186 Moose::Role currently supports all of the functions that L<Moose> exports, but
187 differs slightly in how some items are handled (see L</CAVEATS> below for
190 Moose::Role also offers two role-specific keyword exports:
194 =item B<requires (@method_names)>
196 Roles can require that certain methods are implemented by any class which
199 Note that attribute accessors also count as methods for the purposes
200 of satisfying the requirements of a role.
202 =item B<excludes (@role_names)>
204 Roles can C<exclude> other roles, in effect saying "I can never be combined
205 with these C<@role_names>". This is a feature which should not be used
212 Moose::Role offers a way to remove the keywords it exports, through the
213 C<unimport> method. You simply have to say C<no Moose::Role> at the bottom of
214 your code for this to work.
216 =head2 B<< Moose::Role->init_meta(for_class => $role, metaclass => $metaclass) >>
218 The C<init_meta> method sets up the metaclass object for the role
219 specified by C<for_class>. It also injects a a C<meta> accessor into
220 the role so you can get at this object.
222 The default metaclass is L<Moose::Meta::Role>. You can specify an
223 alternate metaclass with the C<metaclass> parameter.
227 When you use Moose::Role, you can specify which metaclass to use:
229 use Moose::Role -metaclass => 'My::Meta::Role';
231 You can also specify traits which will be applied to your role metaclass:
233 use Moose::Role -traits => 'My::Trait';
235 This is very similar to the attribute traits feature. When you do
236 this, your class's C<meta> object will have the specified traits
237 applied to it. See L<Moose/Metaclass and Trait Name Resolution> for more
240 =head1 APPLYING ROLES
242 In addition to being applied to a class using the 'with' syntax (see
243 L<Moose::Manual::Roles>) and using the L<Moose::Util> 'apply_all_roles'
244 method, roles may also be applied to an instance of a class using
245 L<Moose::Util> 'apply_all_roles' or the role's metaclass:
247 MyApp::Test::SomeRole->meta->apply( $instance );
249 Doing this creates a new, mutable, anonymous subclass, applies the role to that,
250 and reblesses. In a debugger, for example, you will see class names of the
251 form C< Class::MOP::Class::__ANON__::SERIAL::6 >, which means that doing a 'ref'
252 on your instance may not return what you expect. See L<Moose::Object> for 'DOES'.
254 Additional params may be added to the new instance by providing 'rebless_params'.
255 See L<Moose::Meta::Role::Application::ToInstance>.
259 Role support has only a few caveats:
265 Roles cannot use the C<extends> keyword; it will throw an exception for now.
266 The same is true of the C<augment> and C<inner> keywords (not sure those
267 really make sense for roles). All other Moose keywords will be I<deferred>
268 so that they can be applied to the consuming class.
272 Role composition does its best to B<not> be order-sensitive when it comes to
273 conflict resolution and requirements detection. However, it is order-sensitive
274 when it comes to method modifiers. All before/around/after modifiers are
275 included whenever a role is composed into a class, and then applied in the order
276 in which the roles are used. This also means that there is no conflict for
277 before/around/after modifiers.
279 In most cases, this will be a non-issue; however, it is something to keep in
280 mind when using method modifiers in a role. You should never assume any
287 See L<Moose/BUGS> for details on reporting bugs.
291 Stevan Little E<lt>stevan@iinteractive.comE<gt>
293 Christian Hansen E<lt>chansen@cpan.orgE<gt>
295 =head1 COPYRIGHT AND LICENSE
297 Copyright 2006-2010 by Infinity Interactive, Inc.
299 L<http://www.iinteractive.com>
301 This library is free software; you can redistribute it and/or modify
302 it under the same terms as Perl itself.