5 use Scalar::Util 'blessed';
10 our $VERSION = '0.93_02';
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 # make a subtype for each Moose class
116 role_type $role unless find_type_constraint($role);
118 # FIXME copy from Moose.pm
120 if ($role->can('meta')) {
121 $meta = $role->meta();
123 unless ( blessed($meta) && $meta->isa('Moose::Meta::Role') ) {
125 Moose->throw_error("You already have a &meta function, but it does not return a Moose::Meta::Role");
129 $meta = $metaclass->initialize($role);
133 # re-initialize so it inherits properly
134 $metaclass->initialize( ref($_[0]) || $_[0] );
150 Moose::Role - The Moose Role
155 use Moose::Role; # automatically turns on strict and warnings
160 my ($self, $other) = @_;
161 !$self->equal($other);
164 # ... then in your classes
167 use Moose; # automatically turns on strict and warnings
172 my ($self, $other) = @_;
173 $self->as_float == $other->as_float;
178 The concept of roles is documented in L<Moose::Manual::Roles>. This document
179 serves as API documentation.
181 =head1 EXPORTED FUNCTIONS
183 Moose::Role currently supports all of the functions that L<Moose> exports, but
184 differs slightly in how some items are handled (see L<CAVEATS> below for
187 Moose::Role also offers two role-specific keyword exports:
191 =item B<requires (@method_names)>
193 Roles can require that certain methods are implemented by any class which
196 Note that attribute accessors also count as methods for the purposes
197 of satisfying the requirements of a role.
199 =item B<excludes (@role_names)>
201 Roles can C<exclude> other roles, in effect saying "I can never be combined
202 with these C<@role_names>". This is a feature which should not be used
209 Moose::Role offers a way to remove the keywords it exports, through the
210 C<unimport> method. You simply have to say C<no Moose::Role> at the bottom of
211 your code for this to work.
213 =head2 B<< Moose::Role->init_meta(for_class => $role, metaclass => $metaclass) >>
215 The C<init_meta> method sets up the metaclass object for the role
216 specified by C<for_class>. It also injects a a C<meta> accessor into
217 the role so you can get at this object.
219 The default metaclass is L<Moose::Meta::Role>. You can specify an
220 alternate metaclass with the C<metaclass> parameter.
224 When you use Moose::Role, you can specify which metaclass to use:
226 use Moose::Role -metaclass => 'My::Meta::Role';
228 You can also specify traits which will be applied to your role metaclass:
230 use Moose::Role -traits => 'My::Trait';
232 This is very similar to the attribute traits feature. When you do
233 this, your class's C<meta> object will have the specified traits
234 applied to it. See L<Moose/Metaclass and Trait Name Resolution> for more
237 =head1 APPLYING ROLES
239 In addition to being applied to a class using the 'with' syntax (see
240 L<Moose::Manual::Roles>) and using the L<Moose::Util> 'apply_all_roles'
241 method, roles may also be applied to an instance of a class using
242 L<Moose::Util> 'apply_all_roles' or the role's metaclass:
244 MyApp::Test::SomeRole->meta->apply( $instance );
246 Doing this creates a new, mutable, anonymous subclass, applies the role to that,
247 and reblesses. In a debugger, for example, you will see class names of the
248 form C< Class::MOP::Class::__ANON__::SERIAL::6 >, which means that doing a 'ref'
249 on your instance may not return what you expect. See L<Moose::Object> for 'DOES'.
251 Additional params may be added to the new instance by providing 'rebless_params'.
252 See L<Moose::Meta::Role::Application::ToInstance>.
256 Role support has only a few caveats:
262 Roles cannot use the C<extends> keyword; it will throw an exception for now.
263 The same is true of the C<augment> and C<inner> keywords (not sure those
264 really make sense for roles). All other Moose keywords will be I<deferred>
265 so that they can be applied to the consuming class.
269 Role composition does its best to B<not> be order-sensitive when it comes to
270 conflict resolution and requirements detection. However, it is order-sensitive
271 when it comes to method modifiers. All before/around/after modifiers are
272 included whenever a role is composed into a class, and then applied in the order
273 in which the roles are used. This also means that there is no conflict for
274 before/around/after modifiers.
276 In most cases, this will be a non-issue; however, it is something to keep in
277 mind when using method modifiers in a role. You should never assume any
284 See L<Moose/BUGS> for details on reporting bugs.
288 Stevan Little E<lt>stevan@iinteractive.comE<gt>
290 Christian Hansen E<lt>chansen@cpan.orgE<gt>
292 =head1 COPYRIGHT AND LICENSE
294 Copyright 2006-2010 by Infinity Interactive, Inc.
296 L<http://www.iinteractive.com>
298 This library is free software; you can redistribute it and/or modify
299 it under the same terms as Perl itself.