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