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