a4cb4c7e4694a5217d9165028770674ba3872958
[gitmo/Mouse.git] / lib / Mouse / Role.pm
1 package Mouse::Role;
2 use Mouse::Exporter; # enables strict and warnings
3
4 our $VERSION = '0.70';
5
6 use Carp         qw(confess);
7 use Scalar::Util qw(blessed);
8
9 use Mouse::Util  qw(not_supported);
10 use Mouse::Meta::Role;
11 use Mouse ();
12
13 Mouse::Exporter->setup_import_methods(
14     as_is => [qw(
15         extends with
16         has
17         before after around
18         override super
19         augment  inner
20
21         requires excludes
22     ),
23         \&Scalar::Util::blessed,
24         \&Carp::confess,
25     ],
26 );
27
28
29 sub extends  {
30     Carp::croak "Roles do not support 'extends'";
31 }
32
33 sub with     {
34     my $meta = Mouse::Meta::Role->initialize(scalar caller);
35     Mouse::Util::apply_all_roles($meta->name, @_);
36     return;
37 }
38
39 sub has {
40     my $meta = Mouse::Meta::Role->initialize(scalar caller);
41     my $name = shift;
42
43     $meta->throw_error(q{Usage: has 'name' => ( key => value, ... )})
44         if @_ % 2; # odd number of arguments
45
46     for my $n(ref($name) ? @{$name} : $name){
47         $meta->add_attribute($n => @_);
48     }
49     return;
50 }
51
52 sub before {
53     my $meta = Mouse::Meta::Role->initialize(scalar caller);
54     my $code = pop;
55     for my $name($meta->_collect_methods(@_)) {
56         $meta->add_before_method_modifier($name => $code);
57     }
58     return;
59 }
60
61 sub after {
62     my $meta = Mouse::Meta::Role->initialize(scalar caller);
63     my $code = pop;
64     for my $name($meta->_collect_methods(@_)) {
65         $meta->add_after_method_modifier($name => $code);
66     }
67     return;
68 }
69
70 sub around {
71     my $meta = Mouse::Meta::Role->initialize(scalar caller);
72     my $code = pop;
73     for my $name($meta->_collect_methods(@_)) {
74         $meta->add_around_method_modifier($name => $code);
75     }
76     return;
77 }
78
79
80 sub super {
81     return if !defined $Mouse::SUPER_BODY;
82     $Mouse::SUPER_BODY->(@Mouse::SUPER_ARGS);
83 }
84
85 sub override {
86     # my($name, $code) = @_;
87     Mouse::Meta::Role->initialize(scalar caller)->add_override_method_modifier(@_);
88     return;
89 }
90
91 # We keep the same errors messages as Moose::Role emits, here.
92 sub inner {
93     Carp::croak "Roles cannot support 'inner'";
94 }
95
96 sub augment {
97     Carp::croak "Roles cannot support 'augment'";
98 }
99
100 sub requires {
101     my $meta = Mouse::Meta::Role->initialize(scalar caller);
102     $meta->throw_error("Must specify at least one method") unless @_;
103     $meta->add_required_methods(@_);
104     return;
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 VERSION
142
143 This document describes Mouse version 0.70
144
145 =head1 SYNOPSIS
146
147     package MyRole;
148     use Mouse::Role;
149
150 =head1 KEYWORDS
151
152 =head2 C<< meta -> Mouse::Meta::Role >>
153
154 Returns this role's metaclass instance.
155
156 =head2 C<< before (method|methods|regexp) -> CodeRef >>
157
158 Sets up a B<before> method modifier. See L<Moose/before>.
159
160 =head2 C<< after (method|methods|regexp) => CodeRef >>
161
162 Sets up an B<after> method modifier. See L<Moose/after>.
163
164 =head2 C<< around (method|methods|regexp) => CodeRef >>
165
166 Sets up an B<around> method modifier. See L<Moose/around>.
167
168 =head2 C<super>
169
170 Sets up the B<super> keyword. See L<Moose/super>.
171
172 =head2  C<< override method => CodeRef >>
173
174 Sets up an B<override> method modifier. See L<Moose/Role/override>.
175
176 =head2 C<inner>
177
178 This is not supported in roles and emits an error. See L<Moose/Role>.
179
180 =head2 C<< augment method => CodeRef >>
181
182 This is not supported in roles and emits an error. See L<Moose/Role>.
183
184 =head2 C<< has (name|names) => parameters >>
185
186 Sets up an attribute (or if passed an arrayref of names, multiple attributes) to
187 this role. See L<Mouse/has>.
188
189 =head2 C<< confess(error) -> BOOM >>
190
191 L<Carp/confess> for your convenience.
192
193 =head2 C<< blessed(value) -> ClassName | undef >>
194
195 L<Scalar::Util/blessed> for your convenience.
196
197 =head1 MISC
198
199 =head2 import
200
201 Importing Mouse::Role will give you sugar.
202
203 =head2 unimport
204
205 Please unimport (C<< no Mouse::Role >>) so that if someone calls one of the
206 keywords (such as L</has>) it will break loudly instead breaking subtly.
207
208 =head1 SEE ALSO
209
210 L<Moose::Role>
211
212 =cut
213