Commit | Line | Data |
f9e68395 |
1 | package Mouse::Role; |
8bdd9cfc |
2 | use Mouse::Exporter; # enables strict and warnings |
f3bb863f |
3 | |
420d69e8 |
4 | our $VERSION = '0.86'; |
8bdd9cfc |
5 | |
6 | use Carp qw(confess); |
43523060 |
7 | use Scalar::Util qw(blessed); |
f9e68395 |
8 | |
6d28c5cf |
9 | use Mouse (); |
fea36fd2 |
10 | |
11 | Mouse::Exporter->setup_import_methods( |
12 | as_is => [qw( |
13 | extends with |
14 | has |
15 | before after around |
16 | override super |
17 | augment inner |
18 | |
19 | requires excludes |
20 | ), |
21 | \&Scalar::Util::blessed, |
22 | \&Carp::confess, |
23 | ], |
2cb8b713 |
24 | ); |
25 | |
43523060 |
26 | |
9ee0e57c |
27 | sub extends { |
28 | Carp::croak "Roles do not support 'extends'"; |
29 | } |
43523060 |
30 | |
4cc4f8ed |
31 | sub with { |
32 | Mouse::Util::apply_all_roles(scalar(caller), @_); |
9ee0e57c |
33 | return; |
34 | } |
35 | |
36 | sub has { |
37 | my $meta = Mouse::Meta::Role->initialize(scalar caller); |
38 | my $name = shift; |
39 | |
40 | $meta->throw_error(q{Usage: has 'name' => ( key => value, ... )}) |
41 | if @_ % 2; # odd number of arguments |
42 | |
13f78bbc |
43 | for my $n(ref($name) ? @{$name} : $name){ |
44 | $meta->add_attribute($n => @_); |
9ee0e57c |
45 | } |
46 | return; |
47 | } |
b32e8fb9 |
48 | |
49 | sub before { |
8bc2760b |
50 | my $meta = Mouse::Meta::Role->initialize(scalar caller); |
b32e8fb9 |
51 | my $code = pop; |
013ee5f0 |
52 | for my $name($meta->_collect_methods(@_)) { |
53 | $meta->add_before_method_modifier($name => $code); |
b32e8fb9 |
54 | } |
9ee0e57c |
55 | return; |
b32e8fb9 |
56 | } |
57 | |
58 | sub after { |
8bc2760b |
59 | my $meta = Mouse::Meta::Role->initialize(scalar caller); |
b32e8fb9 |
60 | my $code = pop; |
013ee5f0 |
61 | for my $name($meta->_collect_methods(@_)) { |
62 | $meta->add_after_method_modifier($name => $code); |
f9e68395 |
63 | } |
9ee0e57c |
64 | return; |
b32e8fb9 |
65 | } |
66 | |
67 | sub around { |
8bc2760b |
68 | my $meta = Mouse::Meta::Role->initialize(scalar caller); |
b32e8fb9 |
69 | my $code = pop; |
013ee5f0 |
70 | for my $name($meta->_collect_methods(@_)) { |
71 | $meta->add_around_method_modifier($name => $code); |
b32e8fb9 |
72 | } |
9ee0e57c |
73 | return; |
b32e8fb9 |
74 | } |
75 | |
67199842 |
76 | |
77 | sub super { |
85bd3f44 |
78 | return if !defined $Mouse::SUPER_BODY; |
67199842 |
79 | $Mouse::SUPER_BODY->(@Mouse::SUPER_ARGS); |
80 | } |
81 | |
82 | sub override { |
85bd3f44 |
83 | # my($name, $code) = @_; |
84 | Mouse::Meta::Role->initialize(scalar caller)->add_override_method_modifier(@_); |
9ee0e57c |
85 | return; |
67199842 |
86 | } |
87 | |
88 | # We keep the same errors messages as Moose::Role emits, here. |
89 | sub inner { |
6d28c5cf |
90 | Carp::croak "Roles cannot support 'inner'"; |
67199842 |
91 | } |
92 | |
93 | sub augment { |
6d28c5cf |
94 | Carp::croak "Roles cannot support 'augment'"; |
67199842 |
95 | } |
96 | |
59089ec3 |
97 | sub requires { |
8bc2760b |
98 | my $meta = Mouse::Meta::Role->initialize(scalar caller); |
6d28c5cf |
99 | $meta->throw_error("Must specify at least one method") unless @_; |
59089ec3 |
100 | $meta->add_required_methods(@_); |
9ee0e57c |
101 | return; |
59089ec3 |
102 | } |
b32e8fb9 |
103 | |
6d28c5cf |
104 | sub excludes { |
1d76ae62 |
105 | Mouse::Util::not_supported(); |
6d28c5cf |
106 | } |
b32e8fb9 |
107 | |
fea36fd2 |
108 | sub init_meta{ |
9704fe9d |
109 | shift; |
110 | my %args = @_; |
7daedfff |
111 | |
9704fe9d |
112 | my $class = $args{for_class} |
fea36fd2 |
113 | or Carp::confess("Cannot call init_meta without specifying a for_class"); |
b32e8fb9 |
114 | |
fea36fd2 |
115 | my $metaclass = $args{metaclass} || 'Mouse::Meta::Role'; |
7daedfff |
116 | |
9704fe9d |
117 | my $meta = $metaclass->initialize($class); |
7daedfff |
118 | |
fea36fd2 |
119 | $meta->add_method(meta => sub{ |
120 | $metaclass->initialize(ref($_[0]) || $_[0]); |
3a63a2e7 |
121 | }); |
b32e8fb9 |
122 | |
9704fe9d |
123 | # make a role type for each Mouse role |
124 | Mouse::Util::TypeConstraints::role_type($class) |
125 | unless Mouse::Util::TypeConstraints::find_type_constraint($class); |
126 | |
fea36fd2 |
127 | return $meta; |
b32e8fb9 |
128 | } |
f9e68395 |
129 | |
130 | 1; |
131 | |
cadd5b5e |
132 | __END__ |
133 | |
134 | =head1 NAME |
135 | |
1820fffe |
136 | Mouse::Role - The Mouse Role |
137 | |
a25ca8d6 |
138 | =head1 VERSION |
139 | |
420d69e8 |
140 | This document describes Mouse version 0.86 |
a25ca8d6 |
141 | |
1820fffe |
142 | =head1 SYNOPSIS |
143 | |
f5366662 |
144 | package Comparable; |
145 | use Mouse::Role; # the package is now a Mouse role |
146 | |
147 | # Declare methods that are required by this role |
148 | requires qw(compare); |
149 | |
150 | # Define methods this role provides |
151 | sub equals { |
152 | my($self, $other) = @_; |
153 | return $self->compare($other) == 0; |
154 | } |
155 | |
156 | # and later |
157 | package MyObject; |
158 | use Mouse; |
159 | with qw(Comparable); # Now MyObject can equals() |
160 | |
161 | sub compare { |
162 | # ... |
163 | } |
164 | |
165 | my $foo = MyObject->new(); |
166 | my $bar = MyObject->new(); |
167 | $obj->equals($bar); # yes, it is comparable |
cadd5b5e |
168 | |
0f913746 |
169 | =head1 DESCRIPTION |
cadd5b5e |
170 | |
0f913746 |
171 | This module declares the caller class to be a Mouse role. |
cadd5b5e |
172 | |
0f913746 |
173 | The concept of roles is documented in L<Moose::Manual::Roles>. |
174 | This document serves as API documentation. |
cadd5b5e |
175 | |
0f913746 |
176 | =head1 EXPORTED FUNCTIONS |
cadd5b5e |
177 | |
0f913746 |
178 | Mouse::Role supports all of the functions that Mouse exports, but |
179 | differs slightly in how some items are handled (see L</CAVEATS> below |
180 | for details). |
cadd5b5e |
181 | |
0f913746 |
182 | Mouse::Role also offers two role-specific keywords: |
cadd5b5e |
183 | |
0f913746 |
184 | =head2 C<< requires(@method_names) >> |
cadd5b5e |
185 | |
0f913746 |
186 | Roles can require that certain methods are implemented by any class which |
187 | C<does> the role. |
cadd5b5e |
188 | |
0f913746 |
189 | Note that attribute accessors also count as methods for the purposes of |
190 | satisfying the requirements of a role. |
cadd5b5e |
191 | |
0f913746 |
192 | =head2 C<< excludes(@role_names) >> |
67199842 |
193 | |
0f913746 |
194 | This is exported but not implemented in Mouse. |
67199842 |
195 | |
0f913746 |
196 | =head1 IMPORT AND UNIMPORT |
67199842 |
197 | |
0f913746 |
198 | =head2 import |
67199842 |
199 | |
0f913746 |
200 | Importing Mouse::Role will give you sugar. C<-traits> are also supported. |
67199842 |
201 | |
0f913746 |
202 | =head2 unimport |
cadd5b5e |
203 | |
0f913746 |
204 | Please unimport (C<< no Mouse::Role >>) so that if someone calls one of the |
205 | keywords (such as L</has>) it will break loudly instead breaking subtly. |
cadd5b5e |
206 | |
0f913746 |
207 | =head1 CAVEATS |
cadd5b5e |
208 | |
0f913746 |
209 | Role support has only a few caveats: |
cadd5b5e |
210 | |
0f913746 |
211 | =over |
cadd5b5e |
212 | |
0f913746 |
213 | =item * |
cadd5b5e |
214 | |
0f913746 |
215 | Roles cannot use the C<extends> keyword; it will throw an exception for now. |
216 | The same is true of the C<augment> and C<inner> keywords (not sure those |
217 | really make sense for roles). All other Mouse keywords will be I<deferred> |
218 | so that they can be applied to the consuming class. |
cadd5b5e |
219 | |
0f913746 |
220 | =item * |
cadd5b5e |
221 | |
0f913746 |
222 | Role composition does its best to B<not> be order-sensitive when it comes to |
223 | conflict resolution and requirements detection. However, it is order-sensitive |
224 | when it comes to method modifiers. All before/around/after modifiers are |
225 | included whenever a role is composed into a class, and then applied in the order |
226 | in which the roles are used. This also means that there is no conflict for |
227 | before/around/after modifiers. |
cadd5b5e |
228 | |
0f913746 |
229 | In most cases, this will be a non-issue; however, it is something to keep in |
230 | mind when using method modifiers in a role. You should never assume any |
231 | ordering. |
cadd5b5e |
232 | |
0f913746 |
233 | =back |
cadd5b5e |
234 | |
1820fffe |
235 | =head1 SEE ALSO |
236 | |
0f913746 |
237 | L<Mouse> |
238 | |
1820fffe |
239 | L<Moose::Role> |
240 | |
cadd5b5e |
241 | =cut |
242 | |