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