moosedoc
[gitmo/Moose.git] / lib / Moose.pm
CommitLineData
fcd84ca9 1
2package Moose;
3
4use strict;
5use warnings;
6
e185c027 7our $VERSION = '0.04';
fcd84ca9 8
cc65ead0 9use Scalar::Util 'blessed', 'reftype';
fcd84ca9 10use Carp 'confess';
bc1e29b5 11use Sub::Name 'subname';
fcd84ca9 12
7f18097c 13use UNIVERSAL::require;
14
ef1d5f4b 15use Class::MOP;
16
c0e30cf5 17use Moose::Meta::Class;
7415b2cb 18use Moose::Meta::TypeConstraint;
7c13858b 19use Moose::Meta::TypeCoercion;
78cd1d3b 20use Moose::Meta::Attribute;
c0e30cf5 21
fcd84ca9 22use Moose::Object;
7415b2cb 23use Moose::Util::TypeConstraints;
a15dff8d 24
fcd84ca9 25sub import {
26 shift;
27 my $pkg = caller();
28
fc5609d2 29 # we should never export to main
30 return if $pkg eq 'main';
31
a15dff8d 32 Moose::Util::TypeConstraints->import($pkg);
182134e8 33
34 # make a subtype for each Moose class
7415b2cb 35 subtype $pkg
e9ec68d6 36 => as 'Object'
7415b2cb 37 => where { $_->isa($pkg) };
5569c072 38
fcd84ca9 39 my $meta;
40 if ($pkg->can('meta')) {
41 $meta = $pkg->meta();
42 (blessed($meta) && $meta->isa('Class::MOP::Class'))
e185c027 43 || confess "Whoops, not møøsey enough";
fcd84ca9 44 }
45 else {
c0e30cf5 46 $meta = Moose::Meta::Class->initialize($pkg => (
47 ':attribute_metaclass' => 'Moose::Meta::Attribute'
e522431d 48 ));
49 $meta->add_method('meta' => sub {
50 # re-initialize so it inherits properly
51 Moose::Meta::Class->initialize($pkg => (
52 ':attribute_metaclass' => 'Moose::Meta::Attribute'
53 ));
54 })
fcd84ca9 55 }
ad1ac1bd 56
bc1e29b5 57 # NOTE:
58 # &alias_method will install the method, but it
59 # will not name it with
60
61 # handle superclasses
7f18097c 62 $meta->alias_method('extends' => subname 'Moose::extends' => sub {
78cd1d3b 63 _load_all_classes(@_);
7f18097c 64 $meta->superclasses(@_)
5e030bec 65 });
505c6fac 66
78cd1d3b 67 # handle roles
68 $meta->alias_method('with' => subname 'Moose::with' => sub {
69 my ($role) = @_;
70 _load_all_classes($role);
71 $role->meta->apply($meta);
72 });
73
c0e30cf5 74 # handle attributes
29db16a9 75 $meta->alias_method('has' => subname 'Moose::has' => sub {
76 my ($name, %options) = @_;
29db16a9 77 $meta->add_attribute($name, %options)
78 });
3c7278fb 79
c0e30cf5 80 # handle method modifers
bc1e29b5 81 $meta->alias_method('before' => subname 'Moose::before' => sub {
e5ebe4ce 82 my $code = pop @_;
83 $meta->add_before_method_modifier($_, $code) for @_;
84 });
bc1e29b5 85 $meta->alias_method('after' => subname 'Moose::after' => sub {
e5ebe4ce 86 my $code = pop @_;
fc5609d2 87 $meta->add_after_method_modifier($_, $code) for @_;
e5ebe4ce 88 });
bc1e29b5 89 $meta->alias_method('around' => subname 'Moose::around' => sub {
c0e30cf5 90 my $code = pop @_;
fc5609d2 91 $meta->add_around_method_modifier($_, $code) for @_;
c0e30cf5 92 });
b6fe348f 93
94 $meta->alias_method('super' => subname 'Moose::super' => sub {});
95 $meta->alias_method('override' => subname 'Moose::override' => sub {
96 my ($name, $method) = @_;
78cd1d3b 97 $meta->add_override_method_modifier($name => $method);
b6fe348f 98 });
99
100 $meta->alias_method('inner' => subname 'Moose::inner' => sub {});
101 $meta->alias_method('augment' => subname 'Moose::augment' => sub {
102 my ($name, $method) = @_;
78cd1d3b 103 $meta->add_augment_method_modifier($name => $method);
b6fe348f 104 });
5569c072 105
c0e30cf5 106 # make sure they inherit from Moose::Object
5569c072 107 $meta->superclasses('Moose::Object')
108 unless $meta->superclasses();
ad1ac1bd 109
c0e30cf5 110 # we recommend using these things
111 # so export them for them
5569c072 112 $meta->alias_method('confess' => \&Carp::confess);
113 $meta->alias_method('blessed' => \&Scalar::Util::blessed);
fcd84ca9 114}
115
e9bb8a31 116## Utility functions
117
78cd1d3b 118sub _load_all_classes {
e9bb8a31 119 foreach my $super (@_) {
120 # see if this is already
121 # loaded in the symbol table
122 next if _is_class_already_loaded($super);
123 # otherwise require it ...
124 ($super->require)
125 || confess "Could not load superclass '$super' because : " . $UNIVERSAL::require::ERROR;
126 }
127}
128
d7f17ebb 129sub _is_class_already_loaded {
130 my $name = shift;
131 no strict 'refs';
132 return 1 if defined ${"${name}::VERSION"} || defined @{"${name}::ISA"};
133 foreach (keys %{"${name}::"}) {
134 next if substr($_, -2, 2) eq '::';
135 return 1 if defined &{"${name}::$_"};
136 }
137 return 0;
138}
139
fcd84ca9 1401;
141
142__END__
143
144=pod
145
146=head1 NAME
147
e522431d 148Moose - Moose, it's the new Camel
fcd84ca9 149
150=head1 SYNOPSIS
e522431d 151
152 package Point;
153 use Moose;
154
182134e8 155 has 'x' => (isa => 'Int', is => 'rw');
156 has 'y' => (isa => 'Int', is => 'rw');
e522431d 157
158 sub clear {
159 my $self = shift;
160 $self->x(0);
161 $self->y(0);
162 }
163
164 package Point3D;
165 use Moose;
166
167 extends 'Point';
09fdc1dc 168
182134e8 169 has 'z' => (isa => 'Int');
e522431d 170
171 after 'clear' => sub {
172 my $self = shift;
173 $self->{z} = 0;
174 };
175
176=head1 CAVEAT
177
178This is a B<very> early release of this module, it still needs
179some fine tuning and B<lots> more documentation. I am adopting
180the I<release early and release often> approach with this module,
181so keep an eye on your favorite CPAN mirror!
182
fcd84ca9 183=head1 DESCRIPTION
184
e522431d 185Moose is an extension of the Perl 5 object system.
186
187=head2 Another object system!?!?
fcd84ca9 188
e522431d 189Yes, I know there has been an explosion recently of new ways to
190build object's in Perl 5, most of them based on inside-out objects,
191and other such things. Moose is different because it is not a new
192object system for Perl 5, but instead an extension of the existing
193object system.
3c7278fb 194
e522431d 195Moose is built on top of L<Class::MOP>, which is a metaclass system
196for Perl 5. This means that Moose not only makes building normal
505c6fac 197Perl 5 objects better, but it also provides the power of metaclass
198programming.
e522431d 199
200=head2 What does Moose stand for??
201
202Moose doesn't stand for one thing in particular, however, if you
203want, here are a few of my favorites, feel free to contribute
204more :)
205
206=over 4
207
5569c072 208=item Make Other Object Systems Envious
e522431d 209
210=item Makes Object Orientation So Easy
211
5569c072 212=item Makes Object Orientation Spiffy- Er (sorry ingy)
505c6fac 213
5569c072 214=item Most Other Object Systems Emasculate
505c6fac 215
216=item My Overcraft Overfilled (with) Some Eels
217
218=item Moose Often Ovulate Sorta Early
219
505c6fac 220=item Many Overloaded Object Systems Exists
221
222=item Moose Offers Often Super Extensions
223
e522431d 224=back
3c7278fb 225
6ba6d68c 226=head1 BUILDING CLASSES WITH MOOSE
227
228Moose makes every attempt to provide as much convience during class
229construction/definition, but still stay out of your way if you want
230it to. Here are some of the features Moose provides:
231
232Unless specified with C<extends>, any class which uses Moose will
233inherit from L<Moose::Object>.
234
235Moose will also manage all attributes (including inherited ones) that
236are defined with C<has>. And assuming that you call C<new> which is
237inherited from L<Moose::Object>, then this includes properly initializing
238all instance slots, setting defaults where approprtiate and performing any
239type constraint checking or coercion.
240
241=head1 EXPORTED FUNCTIONS
242
243Moose will export a number of functions into the class's namespace, which
244can then be used to set up the class. These functions all work directly
245on the current class.
246
247=over 4
248
249=item B<meta>
250
251This is a method which provides access to the current class's metaclass.
252
253=item B<extends (@superclasses)>
254
255This function will set the superclass(es) for the current class.
256
257This approach is recommended instead of C<use base>, because C<use base>
258actually C<push>es onto the class's C<@ISA>, whereas C<extends> will
259replace it. This is important to ensure that classes which do not have
260superclasses properly inherit from L<Moose::Object>.
261
e9ec68d6 262=item B<with ($role)>
263
264This will apply a given C<$role> to the local class.
265
6ba6d68c 266=item B<has ($name, %options)>
267
268This will install an attribute of a given C<$name> into the current class.
269The list of C<%options> are the same as those provided by both
270L<Class::MOP::Attribute> and L<Moose::Meta::Attribute>, in addition to a
271few convience ones provided by Moose which are listed below:
272
273=over 4
274
076c81ed 275=item I<is =E<gt> 'rw'|'ro'>
6ba6d68c 276
277The I<is> option accepts either I<rw> (for read/write) or I<ro> (for read
278only). These will create either a read/write accessor or a read-only
279accessor respectively, using the same name as the C<$name> of the attribute.
280
281If you need more control over how your accessors are named, you can use the
282I<reader>, I<writer> and I<accessor> options inherited from L<Moose::Meta::Attribute>.
283
076c81ed 284=item I<isa =E<gt> $type_name>
6ba6d68c 285
286The I<isa> option uses Moose's type constraint facilities to set up runtime
287type checking for this attribute. Moose will perform the checks during class
288construction, and within any accessors. The C<$type_name> argument must be a
289string. The string can be either a class name, or a type defined using
290Moose's type defintion features.
291
292=back
293
076c81ed 294=item B<before $name|@names =E<gt> sub { ... }>
6ba6d68c 295
076c81ed 296=item B<after $name|@names =E<gt> sub { ... }>
6ba6d68c 297
076c81ed 298=item B<around $name|@names =E<gt> sub { ... }>
6ba6d68c 299
300This three items are syntactic sugar for the before, after and around method
301modifier features that L<Class::MOP> provides. More information on these can
302be found in the L<Class::MOP> documentation for now.
303
159da176 304=item B<super>
305
306The keyword C<super> is a noop when called outside of an C<override> method. In
307the context of an C<override> method, it will call the next most appropriate
308superclass method with the same arguments as the original method.
309
310=item B<override ($name, &sub)>
311
312An C<override> method, is a way of explictly saying "I am overriding this
313method from my superclass". You can call C<super> within this method, and
314it will work as expected. The same thing I<can> be accomplished with a normal
315method call and the C<SUPER::> pseudo-package, it is really your choice.
316
317=item B<inner>
318
319The keyword C<inner>, much like C<super>, is a no-op outside of the context of
320an C<augment> method. You can think of C<inner> as being the inverse of
321C<super>, the details of how C<inner> and C<augment> work is best described in
322the L<Moose::Cookbook>.
323
324=item B<augment ($name, &sub)>
325
326An C<augment> method, is a way of explictly saying "I am augmenting this
327method from my superclass". Once again, the details of how C<inner> and
328C<augment> work is best described in the L<Moose::Cookbook>.
329
6ba6d68c 330=item B<confess>
331
332This is the C<Carp::confess> function, and exported here beause I use it
333all the time. This feature may change in the future, so you have been warned.
334
335=item B<blessed>
336
337This is the C<Scalar::Uti::blessed> function, it is exported here beause I
338use it all the time. It is highly recommended that this is used instead of
339C<ref> anywhere you need to test for an object's class name.
340
341=back
342
5569c072 343=head1 ACKNOWLEDGEMENTS
344
345=over 4
346
54c189df 347=item I blame Sam Vilain for introducing me to the insanity that is meta-models.
5569c072 348
54c189df 349=item I blame Audrey Tang for then encouraging my meta-model habit in #perl6.
5569c072 350
076c81ed 351=item Without Yuval "nothingmuch" Kogman this module would not be possible,
54c189df 352and it certainly wouldn't have this name ;P
5569c072 353
354=item The basis of the TypeContraints module was Rob Kinyon's idea
355originally, I just ran with it.
356
076c81ed 357=item Thanks to mst & chansen and the whole #moose poose for all the
d46a48f3 358ideas/feature-requests/encouragement
359
5569c072 360=back
361
e90c03d0 362=head1 SEE ALSO
363
364=over 4
365
6ba6d68c 366=item L<Class::MOP> documentation
367
368=item The #moose channel on irc.perl.org
369
e90c03d0 370=item L<http://forum2.org/moose/>
371
159da176 372=item L<http://www.cs.utah.edu/plt/publications/oopsla04-gff.pdf>
373
374This paper (suggested by lbr on #moose) was what lead to the implementation
375of the C<super>/C<overrride> and C<inner>/C<augment> features. If you really
376want to understand this feature, I suggest you read this.
377
e90c03d0 378=back
379
fcd84ca9 380=head1 BUGS
381
382All complex software has bugs lurking in it, and this module is no
383exception. If you find a bug please either email me, or add the bug
384to cpan-RT.
385
fcd84ca9 386=head1 AUTHOR
387
388Stevan Little E<lt>stevan@iinteractive.comE<gt>
389
390=head1 COPYRIGHT AND LICENSE
391
392Copyright 2006 by Infinity Interactive, Inc.
393
394L<http://www.iinteractive.com>
395
396This library is free software; you can redistribute it and/or modify
397it under the same terms as Perl itself.
398
399=cut