version 0.37_03
[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     my($class, %args) = @_;
113
114     my $for_class = $args{for_class}
115         or Carp::confess("Cannot call init_meta without specifying a for_class");
116
117     my $metaclass  = $args{metaclass}  || 'Mouse::Meta::Role';
118
119     my $meta = $metaclass->initialize($for_class);
120
121     $meta->add_method(meta => sub{
122         $metaclass->initialize(ref($_[0]) || $_[0]);
123     });
124
125     return $meta;
126 }
127
128 1;
129
130 __END__
131
132 =head1 NAME
133
134 Mouse::Role - The Mouse Role
135
136 =head1 SYNOPSIS
137
138     package MyRole;
139     use Mouse::Role;
140
141 =head1 KEYWORDS
142
143 =head2 C<< meta -> Mouse::Meta::Role >>
144
145 Returns this role's metaclass instance.
146
147 =head2 C<< before (method|methods) -> CodeRef >>
148
149 Sets up a B<before> method modifier. See L<Moose/before> or
150 L<Class::Method::Modifiers/before>.
151
152 =head2 C<< after (method|methods) => CodeRef >>
153
154 Sets up an B<after> method modifier. See L<Moose/after> or
155 L<Class::Method::Modifiers/after>.
156
157 =head2 C<< around (method|methods) => CodeRef >>
158
159 Sets up an B<around> method modifier. See L<Moose/around> or
160 L<Class::Method::Modifiers/around>.
161
162 =head2 C<super>
163
164 Sets up the B<super> keyword. See L<Moose/super>.
165
166 =head2  C<< override method => CodeRef >>
167
168 Sets up an B<override> method modifier. See L<Moose/Role/override>.
169
170 =head2 C<inner>
171
172 This is not supported in roles and emits an error. See L<Moose/Role>.
173
174 =head2 C<< augment method => CodeRef >>
175
176 This is not supported in roles and emits an error. See L<Moose/Role>.
177
178 =head2 C<< has (name|names) => parameters >>
179
180 Sets up an attribute (or if passed an arrayref of names, multiple attributes) to
181 this role. See L<Mouse/has>.
182
183 =head2 C<< confess(error) -> BOOM >>
184
185 L<Carp/confess> for your convenience.
186
187 =head2 C<< blessed(value) -> ClassName | undef >>
188
189 L<Scalar::Util/blessed> for your convenience.
190
191 =head1 MISC
192
193 =head2 import
194
195 Importing Mouse::Role will give you sugar.
196
197 =head2 unimport
198
199 Please unimport (C<< no Mouse::Role >>) so that if someone calls one of the
200 keywords (such as L</has>) it will break loudly instead breaking subtly.
201
202 =head1 SEE ALSO
203
204 L<Moose::Role>
205
206 =cut
207