Comment
[gitmo/Mouse.git] / lib / Mouse / Role.pm
1 package Mouse::Role;
2 use Mouse::Exporter; # enables strict and warnings
3
4 our $VERSION = '0.76';
5
6 use Carp         qw(confess);
7 use Scalar::Util qw(blessed);
8
9 use Mouse ();
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     ],
24 );
25
26
27 sub extends  {
28     Carp::croak "Roles do not support 'extends'";
29 }
30
31 sub with {
32     Mouse::Util::apply_all_roles(scalar(caller), @_);
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
43     for my $n(ref($name) ? @{$name} : $name){
44         $meta->add_attribute($n => @_);
45     }
46     return;
47 }
48
49 sub before {
50     my $meta = Mouse::Meta::Role->initialize(scalar caller);
51     my $code = pop;
52     for my $name($meta->_collect_methods(@_)) {
53         $meta->add_before_method_modifier($name => $code);
54     }
55     return;
56 }
57
58 sub after {
59     my $meta = Mouse::Meta::Role->initialize(scalar caller);
60     my $code = pop;
61     for my $name($meta->_collect_methods(@_)) {
62         $meta->add_after_method_modifier($name => $code);
63     }
64     return;
65 }
66
67 sub around {
68     my $meta = Mouse::Meta::Role->initialize(scalar caller);
69     my $code = pop;
70     for my $name($meta->_collect_methods(@_)) {
71         $meta->add_around_method_modifier($name => $code);
72     }
73     return;
74 }
75
76
77 sub super {
78     return if !defined $Mouse::SUPER_BODY;
79     $Mouse::SUPER_BODY->(@Mouse::SUPER_ARGS);
80 }
81
82 sub override {
83     # my($name, $code) = @_;
84     Mouse::Meta::Role->initialize(scalar caller)->add_override_method_modifier(@_);
85     return;
86 }
87
88 # We keep the same errors messages as Moose::Role emits, here.
89 sub inner {
90     Carp::croak "Roles cannot support 'inner'";
91 }
92
93 sub augment {
94     Carp::croak "Roles cannot support 'augment'";
95 }
96
97 sub requires {
98     my $meta = Mouse::Meta::Role->initialize(scalar caller);
99     $meta->throw_error("Must specify at least one method") unless @_;
100     $meta->add_required_methods(@_);
101     return;
102 }
103
104 sub excludes {
105     Mouse::Util::not_supported();
106 }
107
108 sub init_meta{
109     shift;
110     my %args = @_;
111
112     my $class = $args{for_class}
113         or Carp::confess("Cannot call init_meta without specifying a for_class");
114
115     my $metaclass  = $args{metaclass}  || 'Mouse::Meta::Role';
116
117     my $meta = $metaclass->initialize($class);
118
119     $meta->add_method(meta => sub{
120         $metaclass->initialize(ref($_[0]) || $_[0]);
121     });
122
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
127     return $meta;
128 }
129
130 1;
131
132 __END__
133
134 =head1 NAME
135
136 Mouse::Role - The Mouse Role
137
138 =head1 VERSION
139
140 This document describes Mouse version 0.76
141
142 =head1 SYNOPSIS
143
144     package MyRole;
145     use Mouse::Role;
146
147 =head1 KEYWORDS
148
149 =head2 C<< meta -> Mouse::Meta::Role >>
150
151 Returns this role's metaclass instance.
152
153 =head2 C<< before (method|methods|regexp) -> CodeRef >>
154
155 Sets up a B<before> method modifier. See L<Moose/before>.
156
157 =head2 C<< after (method|methods|regexp) => CodeRef >>
158
159 Sets up an B<after> method modifier. See L<Moose/after>.
160
161 =head2 C<< around (method|methods|regexp) => CodeRef >>
162
163 Sets up an B<around> method modifier. See L<Moose/around>.
164
165 =head2 C<super>
166
167 Sets up the B<super> keyword. See L<Moose/super>.
168
169 =head2  C<< override method => CodeRef >>
170
171 Sets up an B<override> method modifier. See L<Moose/Role/override>.
172
173 =head2 C<inner>
174
175 This is not supported in roles and emits an error. See L<Moose/Role>.
176
177 =head2 C<< augment method => CodeRef >>
178
179 This is not supported in roles and emits an error. See L<Moose/Role>.
180
181 =head2 C<< has (name|names) => parameters >>
182
183 Sets up an attribute (or if passed an arrayref of names, multiple attributes) to
184 this role. See L<Mouse/has>.
185
186 =head2 C<< confess(error) -> BOOM >>
187
188 L<Carp/confess> for your convenience.
189
190 =head2 C<< blessed(value) -> ClassName | undef >>
191
192 L<Scalar::Util/blessed> for your convenience.
193
194 =head1 MISC
195
196 =head2 import
197
198 Importing Mouse::Role will give you sugar.
199
200 =head2 unimport
201
202 Please unimport (C<< no Mouse::Role >>) so that if someone calls one of the
203 keywords (such as L</has>) it will break loudly instead breaking subtly.
204
205 =head1 SEE ALSO
206
207 L<Moose::Role>
208
209 =cut
210