Implement the "eval $VERSION" trick from perlmodstyle so CPAN doesn't
[gitmo/Moose.git] / lib / Moose / Role.pm
CommitLineData
e185c027 1
2package Moose::Role;
3
4use strict;
5use warnings;
6
e65dccbc 7use Scalar::Util 'blessed';
cc5e6b6f 8use Carp 'confess', 'croak';
e185c027 9
c4538447 10use Data::OptList;
2d562421 11use Sub::Exporter;
12
75b95414 13our $VERSION = '0.55_01';
14$VERSION = eval $VERSION;
d44714be 15our $AUTHORITY = 'cpan:STEVAN';
e185c027 16
d7d8a8c7 17use Moose ();
18use Moose::Util ();
e65dccbc 19
e185c027 20use Moose::Meta::Role;
7eaef7ad 21use Moose::Util::TypeConstraints;
e185c027 22
5bd4db9b 23sub extends {
24 croak "Roles do not currently support 'extends'";
25}
fb1e11d5 26
5bd4db9b 27sub with {
acbc8892 28 Moose::Util::apply_all_roles( Moose::Meta::Role->initialize(shift), @_ );
5bd4db9b 29}
2d562421 30
5bd4db9b 31sub requires {
acbc8892 32 my $meta = Moose::Meta::Role->initialize(shift);
5bd4db9b 33 croak "Must specify at least one method" unless @_;
34 $meta->add_required_methods(@_);
35}
fb1e11d5 36
5bd4db9b 37sub excludes {
acbc8892 38 my $meta = Moose::Meta::Role->initialize(shift);
5bd4db9b 39 croak "Must specify at least one role" unless @_;
40 $meta->add_excluded_roles(@_);
41}
fc9a40d7 42
5bd4db9b 43sub has {
acbc8892 44 my $meta = Moose::Meta::Role->initialize(shift);
5bd4db9b 45 my $name = shift;
46 croak 'Usage: has \'name\' => ( key => value, ... )' if @_ == 1;
47 my %options = @_;
48 my $attrs = ( ref($name) eq 'ARRAY' ) ? $name : [ ($name) ];
49 $meta->add_attribute( $_, %options ) for @$attrs;
50}
fb1e11d5 51
5bd4db9b 52sub before {
acbc8892 53 my $meta = Moose::Meta::Role->initialize(shift);
5bd4db9b 54 my $code = pop @_;
2d562421 55
5bd4db9b 56 for (@_) {
57 croak "Moose::Role do not currently support "
58 . ref($_)
59 . " references for before method modifiers"
60 if ref $_;
61 $meta->add_before_method_modifier( $_, $code );
62 }
63}
64
65sub after {
acbc8892 66 my $meta = Moose::Meta::Role->initialize(shift);
5bd4db9b 67
68 my $code = pop @_;
69 for (@_) {
70 croak "Moose::Role do not currently support "
71 . ref($_)
72 . " references for after method modifiers"
73 if ref $_;
74 $meta->add_after_method_modifier( $_, $code );
75 }
76}
2d562421 77
5bd4db9b 78sub around {
acbc8892 79 my $meta = Moose::Meta::Role->initialize(shift);
5bd4db9b 80 my $code = pop @_;
81 for (@_) {
82 croak "Moose::Role do not currently support "
83 . ref($_)
84 . " references for around method modifiers"
85 if ref $_;
86 $meta->add_around_method_modifier( $_, $code );
87 }
88}
2d562421 89
5bd4db9b 90# see Moose.pm for discussion
91sub super {
92 return unless $Moose::SUPER_BODY;
93 $Moose::SUPER_BODY->(@Moose::SUPER_ARGS);
94}
d31f9614 95
5bd4db9b 96sub override {
acbc8892 97 my $meta = Moose::Meta::Role->initialize(shift);
5bd4db9b 98 my ( $name, $code ) = @_;
99 $meta->add_override_method_modifier( $name, $code );
100}
d31f9614 101
5bd4db9b 102sub inner {
103 croak "Moose::Role cannot support 'inner'";
104}
d31f9614 105
5bd4db9b 106sub augment {
107 croak "Moose::Role cannot support 'augment'";
108}
d31f9614 109
aedcb7d9 110my $exporter = Moose::Exporter->setup_import_methods(
97a93056 111 with_caller => [
112 qw( with requires excludes has before after around override make_immutable )
113 ],
114 as_is => [
115 qw( extends super inner augment ),
5bd4db9b 116 \&Carp::confess,
117 \&Scalar::Util::blessed,
118 ],
119);
120
0474f1d0 121sub init_meta {
122 shift;
123 my %args = @_;
cbb03d24 124
0474f1d0 125 my $role = $args{for_class}
126 or confess
127 "Cannot call init_meta without specifying a for_class";
0338a411 128
0474f1d0 129 my $metaclass = $args{metaclass} || "Moose::Meta::Role";
cbb03d24 130
0474f1d0 131 # make a subtype for each Moose class
132 role_type $role unless find_type_constraint($role);
cbb03d24 133
0474f1d0 134 # FIXME copy from Moose.pm
135 my $meta;
136 if ($role->can('meta')) {
137 $meta = $role->meta();
138 (blessed($meta) && $meta->isa('Moose::Meta::Role'))
139 || confess "You already have a &meta function, but it does not return a Moose::Meta::Role";
cbb03d24 140 }
0474f1d0 141 else {
142 $meta = $metaclass->initialize($role);
143 $meta->alias_method('meta' => sub { $meta });
144 }
145
146 return $meta;
cbb03d24 147}
148
e185c027 1491;
150
151__END__
152
153=pod
154
155=head1 NAME
156
157Moose::Role - The Moose Role
158
76d37e5a 159=head1 SYNOPSIS
160
161 package Eq;
85424612 162 use Moose::Role; # automatically turns on strict and warnings
fb1e11d5 163
e46edf94 164 requires 'equal';
fb1e11d5 165
166 sub no_equal {
76d37e5a 167 my ($self, $other) = @_;
168 !$self->equal($other);
169 }
fb1e11d5 170
76d37e5a 171 # ... then in your classes
fb1e11d5 172
76d37e5a 173 package Currency;
85424612 174 use Moose; # automatically turns on strict and warnings
fb1e11d5 175
76d37e5a 176 with 'Eq';
fb1e11d5 177
76d37e5a 178 sub equal {
179 my ($self, $other) = @_;
bdabd620 180 $self->as_float == $other->as_float;
76d37e5a 181 }
182
e185c027 183=head1 DESCRIPTION
184
85424612 185Role support in Moose is pretty solid at this point. However, the best
186documentation is still the the test suite. It is fairly safe to assume Perl 6
187style behavior and then either refer to the test suite, or ask questions on
188#moose if something doesn't quite do what you expect.
d44714be 189
85424612 190We are planning writing some more documentation in the near future, but nothing
191is ready yet, sorry.
76d37e5a 192
2c0cbef7 193=head1 EXPORTED FUNCTIONS
194
85424612 195Moose::Role currently supports all of the functions that L<Moose> exports, but
196differs slightly in how some items are handled (see L<CAVEATS> below for
197details).
76d37e5a 198
85424612 199Moose::Role also offers two role-specific keyword exports:
e185c027 200
201=over 4
202
2c0cbef7 203=item B<requires (@method_names)>
76d37e5a 204
fb1e11d5 205Roles can require that certain methods are implemented by any class which
85424612 206C<does> the role.
9e93dd19 207
2c0cbef7 208=item B<excludes (@role_names)>
209
9e93dd19 210Roles can C<exclude> other roles, in effect saying "I can never be combined
fb1e11d5 211with these C<@role_names>". This is a feature which should not be used
85424612 212lightly.
9e93dd19 213
2c0cbef7 214=back
215
d31f9614 216=head2 B<unimport>
217
218Moose::Role offers a way to remove the keywords it exports, through the
219C<unimport> method. You simply have to say C<no Moose::Role> at the bottom of
220your code for this to work.
221
1ccc7f8a 222=head2 B<< Moose::Role->init_meta(for_class => $role, metaclass => $metaclass) >>
223
224The C<init_meta> method sets up the metaclass object for the role
225specified by C<for_class>. It also injects a a C<meta> accessor into
226the role so you can get at this object.
227
90ef0366 228The default metaclass is L<Moose::Meta::Role>. You can specify an
1ccc7f8a 229alternate metaclass with the C<metaclass> parameter.
230
2c0cbef7 231=head1 CAVEATS
232
85424612 233Role support has only a few caveats:
2c0cbef7 234
235=over 4
76d37e5a 236
76d37e5a 237=item *
238
fb1e11d5 239Roles cannot use the C<extends> keyword; it will throw an exception for now.
240The same is true of the C<augment> and C<inner> keywords (not sure those
241really make sense for roles). All other Moose keywords will be I<deferred>
85424612 242so that they can be applied to the consuming class.
76d37e5a 243
fb1e11d5 244=item *
2c0cbef7 245
85424612 246Role composition does its best to B<not> be order-sensitive when it comes to
247conflict resolution and requirements detection. However, it is order-sensitive
248when it comes to method modifiers. All before/around/after modifiers are
249included whenever a role is composed into a class, and then applied in the order
250in which the roles are used. This also means that there is no conflict for
251before/around/after modifiers.
2c0cbef7 252
85424612 253In most cases, this will be a non-issue; however, it is something to keep in
254mind when using method modifiers in a role. You should never assume any
2c0cbef7 255ordering.
256
257=item *
258
fb1e11d5 259The C<requires> keyword currently only works with actual methods. A method
260modifier (before/around/after and override) will not count as a fufillment
2c0cbef7 261of the requirement, and neither will an autogenerated accessor for an attribute.
262
85424612 263It is likely that attribute accessors will eventually be allowed to fufill those
264requirements, or we will introduce a C<requires_attr> keyword of some kind
265instead. This decision has not yet been finalized.
2c0cbef7 266
e185c027 267=back
268
269=head1 BUGS
270
fb1e11d5 271All complex software has bugs lurking in it, and this module is no
e185c027 272exception. If you find a bug please either email me, or add the bug
273to cpan-RT.
274
275=head1 AUTHOR
276
277Stevan Little E<lt>stevan@iinteractive.comE<gt>
278
db1ab48d 279Christian Hansen E<lt>chansen@cpan.orgE<gt>
98aae381 280
e185c027 281=head1 COPYRIGHT AND LICENSE
282
778db3ac 283Copyright 2006-2008 by Infinity Interactive, Inc.
e185c027 284
285L<http://www.iinteractive.com>
286
287This library is free software; you can redistribute it and/or modify
fb1e11d5 288it under the same terms as Perl itself.
e185c027 289
68117c45 290=cut