I realized that all the "with caller" wrapper stuff is pointless. We
[gitmo/Moose.git] / lib / Moose / Role.pm
CommitLineData
e185c027 1
2package Moose::Role;
3
4use strict;
5use warnings;
6
e65dccbc 7use Scalar::Util 'blessed';
cc5e6b6f 8use Carp 'confess', 'croak';
e185c027 9
c4538447 10use Data::OptList;
2d562421 11use Sub::Exporter;
12
a94188ac 13our $VERSION = '0.56';
d44714be 14our $AUTHORITY = 'cpan:STEVAN';
e185c027 15
d7d8a8c7 16use Moose ();
17use Moose::Util ();
e65dccbc 18
e185c027 19use Moose::Meta::Role;
7eaef7ad 20use Moose::Util::TypeConstraints;
e185c027 21
5bd4db9b 22sub extends {
23 croak "Roles do not currently support 'extends'";
24}
fb1e11d5 25
5bd4db9b 26sub with {
2f29843c 27 my $role = caller();
28 Moose::Util::apply_all_roles( $role->meta(), @_ );
5bd4db9b 29}
2d562421 30
5bd4db9b 31sub requires {
2f29843c 32 my $role = caller();
33 my $meta = $role->meta();
5bd4db9b 34 croak "Must specify at least one method" unless @_;
35 $meta->add_required_methods(@_);
36}
fb1e11d5 37
5bd4db9b 38sub excludes {
2f29843c 39 my $role = caller();
40 my $meta = $role->meta();
5bd4db9b 41 croak "Must specify at least one role" unless @_;
42 $meta->add_excluded_roles(@_);
43}
fc9a40d7 44
5bd4db9b 45sub has {
2f29843c 46 my $role = caller();
47 my $meta = $role->meta();
5bd4db9b 48 my $name = shift;
49 croak 'Usage: has \'name\' => ( key => value, ... )' if @_ == 1;
50 my %options = @_;
51 my $attrs = ( ref($name) eq 'ARRAY' ) ? $name : [ ($name) ];
52 $meta->add_attribute( $_, %options ) for @$attrs;
53}
fb1e11d5 54
5bd4db9b 55sub before {
2f29843c 56 my $role = caller();
57 my $meta = $role->meta();
5bd4db9b 58 my $code = pop @_;
2d562421 59
5bd4db9b 60 for (@_) {
61 croak "Moose::Role do not currently support "
62 . ref($_)
63 . " references for before method modifiers"
64 if ref $_;
65 $meta->add_before_method_modifier( $_, $code );
66 }
67}
68
69sub after {
2f29843c 70 my $role = caller();
71 my $meta = $role->meta();
5bd4db9b 72
73 my $code = pop @_;
74 for (@_) {
75 croak "Moose::Role do not currently support "
76 . ref($_)
77 . " references for after method modifiers"
78 if ref $_;
79 $meta->add_after_method_modifier( $_, $code );
80 }
81}
2d562421 82
5bd4db9b 83sub around {
2f29843c 84 my $role = caller();
85 my $meta = $role->meta();
5bd4db9b 86 my $code = pop @_;
87 for (@_) {
88 croak "Moose::Role do not currently support "
89 . ref($_)
90 . " references for around method modifiers"
91 if ref $_;
92 $meta->add_around_method_modifier( $_, $code );
93 }
94}
2d562421 95
5bd4db9b 96# see Moose.pm for discussion
97sub super {
98 return unless $Moose::SUPER_BODY;
99 $Moose::SUPER_BODY->(@Moose::SUPER_ARGS);
100}
d31f9614 101
5bd4db9b 102sub override {
2f29843c 103 my $role = caller();
104 my $meta = $role->meta();
5bd4db9b 105 my ( $name, $code ) = @_;
106 $meta->add_override_method_modifier( $name, $code );
107}
d31f9614 108
5bd4db9b 109sub inner {
110 croak "Moose::Role cannot support 'inner'";
111}
d31f9614 112
5bd4db9b 113sub augment {
114 croak "Moose::Role cannot support 'augment'";
115}
d31f9614 116
a5c426fc 117my $exporter = Moose::Exporter->build_import_methods(
2f29843c 118 export => [
119 qw( with requires excludes has before after around override extends super inner augment ),
5bd4db9b 120 \&Carp::confess,
121 \&Scalar::Util::blessed,
122 ],
123);
124
cbb03d24 125{
126 my %METAS;
127
0338a411 128 sub _init_meta {
129 shift;
130 my %args = @_;
131
132 my $role = $args{for_class}
133 or confess
134 "Cannot call _init_meta without specifying a for_class";
cbb03d24 135
136 return $METAS{$role} if exists $METAS{$role};
137
138 # make a subtype for each Moose class
139 role_type $role unless find_type_constraint($role);
140
141 my $meta;
142 if ($role->can('meta')) {
143 $meta = $role->meta();
144 (blessed($meta) && $meta->isa('Moose::Meta::Role'))
145 || confess "You already have a &meta function, but it does not return a Moose::Meta::Role";
146 }
147 else {
148 $meta = Moose::Meta::Role->initialize($role);
149 $meta->alias_method('meta' => sub { $meta });
150 }
151
152 return $METAS{$role} = $meta;
153 }
154}
155
e185c027 1561;
157
158__END__
159
160=pod
161
162=head1 NAME
163
164Moose::Role - The Moose Role
165
76d37e5a 166=head1 SYNOPSIS
167
168 package Eq;
85424612 169 use Moose::Role; # automatically turns on strict and warnings
fb1e11d5 170
e46edf94 171 requires 'equal';
fb1e11d5 172
173 sub no_equal {
76d37e5a 174 my ($self, $other) = @_;
175 !$self->equal($other);
176 }
fb1e11d5 177
76d37e5a 178 # ... then in your classes
fb1e11d5 179
76d37e5a 180 package Currency;
85424612 181 use Moose; # automatically turns on strict and warnings
fb1e11d5 182
76d37e5a 183 with 'Eq';
fb1e11d5 184
76d37e5a 185 sub equal {
186 my ($self, $other) = @_;
bdabd620 187 $self->as_float == $other->as_float;
76d37e5a 188 }
189
e185c027 190=head1 DESCRIPTION
191
85424612 192Role support in Moose is pretty solid at this point. However, the best
193documentation is still the the test suite. It is fairly safe to assume Perl 6
194style behavior and then either refer to the test suite, or ask questions on
195#moose if something doesn't quite do what you expect.
d44714be 196
85424612 197We are planning writing some more documentation in the near future, but nothing
198is ready yet, sorry.
76d37e5a 199
2c0cbef7 200=head1 EXPORTED FUNCTIONS
201
85424612 202Moose::Role currently supports all of the functions that L<Moose> exports, but
203differs slightly in how some items are handled (see L<CAVEATS> below for
204details).
76d37e5a 205
85424612 206Moose::Role also offers two role-specific keyword exports:
e185c027 207
208=over 4
209
2c0cbef7 210=item B<requires (@method_names)>
76d37e5a 211
fb1e11d5 212Roles can require that certain methods are implemented by any class which
85424612 213C<does> the role.
9e93dd19 214
2c0cbef7 215=item B<excludes (@role_names)>
216
9e93dd19 217Roles can C<exclude> other roles, in effect saying "I can never be combined
fb1e11d5 218with these C<@role_names>". This is a feature which should not be used
85424612 219lightly.
9e93dd19 220
2c0cbef7 221=back
222
d31f9614 223=head2 B<unimport>
224
225Moose::Role offers a way to remove the keywords it exports, through the
226C<unimport> method. You simply have to say C<no Moose::Role> at the bottom of
227your code for this to work.
228
2c0cbef7 229=head1 CAVEATS
230
85424612 231Role support has only a few caveats:
2c0cbef7 232
233=over 4
76d37e5a 234
76d37e5a 235=item *
236
fb1e11d5 237Roles cannot use the C<extends> keyword; it will throw an exception for now.
238The same is true of the C<augment> and C<inner> keywords (not sure those
239really make sense for roles). All other Moose keywords will be I<deferred>
85424612 240so that they can be applied to the consuming class.
76d37e5a 241
fb1e11d5 242=item *
2c0cbef7 243
85424612 244Role composition does its best to B<not> be order-sensitive when it comes to
245conflict resolution and requirements detection. However, it is order-sensitive
246when it comes to method modifiers. All before/around/after modifiers are
247included whenever a role is composed into a class, and then applied in the order
248in which the roles are used. This also means that there is no conflict for
249before/around/after modifiers.
2c0cbef7 250
85424612 251In most cases, this will be a non-issue; however, it is something to keep in
252mind when using method modifiers in a role. You should never assume any
2c0cbef7 253ordering.
254
255=item *
256
fb1e11d5 257The C<requires> keyword currently only works with actual methods. A method
258modifier (before/around/after and override) will not count as a fufillment
2c0cbef7 259of the requirement, and neither will an autogenerated accessor for an attribute.
260
85424612 261It is likely that attribute accessors will eventually be allowed to fufill those
262requirements, or we will introduce a C<requires_attr> keyword of some kind
263instead. This decision has not yet been finalized.
2c0cbef7 264
e185c027 265=back
266
267=head1 BUGS
268
fb1e11d5 269All complex software has bugs lurking in it, and this module is no
e185c027 270exception. If you find a bug please either email me, or add the bug
271to cpan-RT.
272
273=head1 AUTHOR
274
275Stevan Little E<lt>stevan@iinteractive.comE<gt>
276
db1ab48d 277Christian Hansen E<lt>chansen@cpan.orgE<gt>
98aae381 278
e185c027 279=head1 COPYRIGHT AND LICENSE
280
778db3ac 281Copyright 2006-2008 by Infinity Interactive, Inc.
e185c027 282
283L<http://www.iinteractive.com>
284
285This library is free software; you can redistribute it and/or modify
fb1e11d5 286it under the same terms as Perl itself.
e185c027 287
68117c45 288=cut