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