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