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