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