foo
[gitmo/Moose.git] / lib / Moose.pm
CommitLineData
fcd84ca9 1
be33e4f3 2use lib '/Users/stevan/Projects/CPAN/Class-MOP/Class-MOP/lib';
3
fcd84ca9 4package Moose;
5
6use strict;
7use warnings;
8
2d562421 9our $VERSION = '0.05';
fcd84ca9 10
cc65ead0 11use Scalar::Util 'blessed', 'reftype';
fcd84ca9 12use Carp 'confess';
bc1e29b5 13use Sub::Name 'subname';
fcd84ca9 14
7f18097c 15use UNIVERSAL::require;
2d562421 16use Sub::Exporter;
7f18097c 17
ef1d5f4b 18use Class::MOP;
19
c0e30cf5 20use Moose::Meta::Class;
7415b2cb 21use Moose::Meta::TypeConstraint;
7c13858b 22use Moose::Meta::TypeCoercion;
78cd1d3b 23use Moose::Meta::Attribute;
ddd0ec20 24use Moose::Meta::Instance;
c0e30cf5 25
fcd84ca9 26use Moose::Object;
7415b2cb 27use Moose::Util::TypeConstraints;
a15dff8d 28
a3c7e2fe 29{
be33e4f3 30 my $CALLER;
a3c7e2fe 31
be33e4f3 32 sub _init_meta {
a3c7e2fe 33 my $class = $CALLER;
34
a3c7e2fe 35 # make a subtype for each Moose class
36 subtype $class
37 => as 'Object'
38 => where { $_->isa($class) }
39 unless find_type_constraint($class);
40
41 my $meta;
42 if ($class->can('meta')) {
fcec2383 43 # NOTE:
44 # this is the case where the metaclass pragma
45 # was used before the 'use Moose' statement to
46 # override a specific class
a3c7e2fe 47 $meta = $class->meta();
48 (blessed($meta) && $meta->isa('Moose::Meta::Class'))
49 || confess "Whoops, not møøsey enough";
50 }
51 else {
fcec2383 52 # NOTE:
53 # this is broken currently, we actually need
54 # to allow the possiblity of an inherited
55 # meta, which will not be visible until the
56 # user 'extends' first. This needs to have
57 # more intelligence to it
590868a3 58 $meta = Moose::Meta::Class->initialize($class);
a3c7e2fe 59 $meta->add_method('meta' => sub {
60 # re-initialize so it inherits properly
fcb7afc2 61 Moose::Meta::Class->initialize(blessed($_[0]) || $_[0]);
a3c7e2fe 62 })
63 }
64
65 # make sure they inherit from Moose::Object
66 $meta->superclasses('Moose::Object')
67 unless $meta->superclasses();
a3c7e2fe 68 }
69
70 my %exports = (
71 extends => sub {
be33e4f3 72 my $class = $CALLER;
3d544ed5 73 return subname 'Moose::extends' => sub {
a3c7e2fe 74 _load_all_classes(@_);
be33e4f3 75 my $meta = $class->meta;
76 foreach my $super (@_) {
77 # don't bother if it does not have a meta.
78 next unless $super->can('meta');
79 # if it's meta is a vanilla Moose,
80 # then we can safely ignore it.
81 next if blessed($super->meta) eq 'Moose::Meta::Class';
82 # but if we have anything else,
83 # we need to check it out ...
84 unless (# see if of our metaclass is incompatible
85 $meta->isa(blessed($super->meta)) &&
86 # see if our instance metaclass is incompatible
87 $meta->instance_metaclass->isa($super->meta->instance_metaclass) &&
88 # ... and if we are just a vanilla Moose
89 $meta->isa('Moose::Meta::Class')) {
90 # re-initialize the meta ...
91 my $super_meta = $super->meta;
92 $meta = $super_meta->reinitialize($class => (
93 ':attribute_metaclass' => $super_meta->attribute_metaclass,
94 ':method_metaclass' => $super_meta->method_metaclass,
95 ':instance_metaclass' => $super_meta->instance_metaclass,
96 ));
97 }
98 }
99 $meta->superclasses(@_);
a3c7e2fe 100 };
101 },
102 with => sub {
be33e4f3 103 my $class = $CALLER;
3d544ed5 104 return subname 'Moose::with' => sub {
a3c7e2fe 105 my ($role) = @_;
106 _load_all_classes($role);
be33e4f3 107 $role->meta->apply($class->meta);
a3c7e2fe 108 };
109 },
110 has => sub {
be33e4f3 111 my $class = $CALLER;
3d544ed5 112 return subname 'Moose::has' => sub {
a3c7e2fe 113 my ($name, %options) = @_;
be33e4f3 114 my $meta = $class->meta;
2d2b92e5 115 if ($name =~ /^\+(.*)/) {
1d768fb1 116 my $inherited_attr = $meta->find_attribute_by_name($1);
117 (defined $inherited_attr)
118 || confess "Could not find an attribute by the name of '$1' to inherit from";
ce0e8d63 119 my $new_attr = $inherited_attr->clone_and_inherit_options(%options);
1d768fb1 120 $meta->add_attribute($new_attr);
b0ea39ef 121 }
122 else {
2d2b92e5 123 if ($options{metaclass}) {
124 _load_all_classes($options{metaclass});
125 $meta->add_attribute($options{metaclass}->new($name, %options));
126 }
127 else {
128 $meta->add_attribute($name, %options);
129 }
b0ea39ef 130 }
a3c7e2fe 131 };
132 },
133 before => sub {
be33e4f3 134 my $class = $CALLER;
3d544ed5 135 return subname 'Moose::before' => sub {
a3c7e2fe 136 my $code = pop @_;
be33e4f3 137 my $meta = $class->meta;
a3c7e2fe 138 $meta->add_before_method_modifier($_, $code) for @_;
139 };
140 },
141 after => sub {
be33e4f3 142 my $class = $CALLER;
3d544ed5 143 return subname 'Moose::after' => sub {
a3c7e2fe 144 my $code = pop @_;
be33e4f3 145 my $meta = $class->meta;
a3c7e2fe 146 $meta->add_after_method_modifier($_, $code) for @_;
147 };
148 },
149 around => sub {
be33e4f3 150 my $class = $CALLER;
3d544ed5 151 return subname 'Moose::around' => sub {
a3c7e2fe 152 my $code = pop @_;
be33e4f3 153 my $meta = $class->meta;
a3c7e2fe 154 $meta->add_around_method_modifier($_, $code) for @_;
155 };
156 },
157 super => sub {
3d544ed5 158 return subname 'Moose::super' => sub {};
a3c7e2fe 159 },
160 override => sub {
be33e4f3 161 my $class = $CALLER;
3d544ed5 162 return subname 'Moose::override' => sub {
a3c7e2fe 163 my ($name, $method) = @_;
be33e4f3 164 $class->meta->add_override_method_modifier($name => $method);
a3c7e2fe 165 };
166 },
167 inner => sub {
3d544ed5 168 return subname 'Moose::inner' => sub {};
a3c7e2fe 169 },
170 augment => sub {
be33e4f3 171 my $class = $CALLER;
3d544ed5 172 return subname 'Moose::augment' => sub {
a3c7e2fe 173 my ($name, $method) = @_;
be33e4f3 174 $class->meta->add_augment_method_modifier($name => $method);
a3c7e2fe 175 };
176 },
177 confess => sub {
178 return \&Carp::confess;
179 },
180 blessed => sub {
181 return \&Scalar::Util::blessed;
54b1cdf0 182 },
183 all_methods => sub {
065b95d5 184 subname 'Moose::all_methods' => sub () {
54b1cdf0 185 sub {
9eacbf7c 186 my ($class, $delegate_class) = @_;
54b1cdf0 187 $delegate_class->compute_all_applicable_methods();
188 }
189 }
a3c7e2fe 190 }
191 );
3d544ed5 192
a3c7e2fe 193 my $exporter = Sub::Exporter::build_exporter({
194 exports => \%exports,
195 groups => {
196 default => [':all']
197 }
198 });
199
fcb7afc2 200 sub import {
a3c7e2fe 201 $CALLER = caller();
202
203 # we should never export to main
204 return if $CALLER eq 'main';
be33e4f3 205
206 _init_meta();
9eacbf7c 207
a3c7e2fe 208 goto $exporter;
fcb7afc2 209 }
fcd84ca9 210}
211
e9bb8a31 212## Utility functions
213
78cd1d3b 214sub _load_all_classes {
e9bb8a31 215 foreach my $super (@_) {
216 # see if this is already
217 # loaded in the symbol table
218 next if _is_class_already_loaded($super);
219 # otherwise require it ...
220 ($super->require)
221 || confess "Could not load superclass '$super' because : " . $UNIVERSAL::require::ERROR;
222 }
223}
224
d7f17ebb 225sub _is_class_already_loaded {
226 my $name = shift;
227 no strict 'refs';
228 return 1 if defined ${"${name}::VERSION"} || defined @{"${name}::ISA"};
229 foreach (keys %{"${name}::"}) {
230 next if substr($_, -2, 2) eq '::';
231 return 1 if defined &{"${name}::$_"};
232 }
233 return 0;
234}
235
fcd84ca9 2361;
237
238__END__
239
240=pod
241
242=head1 NAME
243
e522431d 244Moose - Moose, it's the new Camel
fcd84ca9 245
246=head1 SYNOPSIS
e522431d 247
248 package Point;
249 use Moose;
250
182134e8 251 has 'x' => (isa => 'Int', is => 'rw');
252 has 'y' => (isa => 'Int', is => 'rw');
e522431d 253
254 sub clear {
255 my $self = shift;
256 $self->x(0);
257 $self->y(0);
258 }
259
260 package Point3D;
261 use Moose;
262
263 extends 'Point';
09fdc1dc 264
182134e8 265 has 'z' => (isa => 'Int');
e522431d 266
267 after 'clear' => sub {
268 my $self = shift;
269 $self->{z} = 0;
270 };
271
272=head1 CAVEAT
273
79592a54 274This is an early release of this module, it still needs
e522431d 275some fine tuning and B<lots> more documentation. I am adopting
276the I<release early and release often> approach with this module,
277so keep an eye on your favorite CPAN mirror!
278
fcd84ca9 279=head1 DESCRIPTION
280
e522431d 281Moose is an extension of the Perl 5 object system.
282
283=head2 Another object system!?!?
fcd84ca9 284
e522431d 285Yes, I know there has been an explosion recently of new ways to
286build object's in Perl 5, most of them based on inside-out objects,
287and other such things. Moose is different because it is not a new
288object system for Perl 5, but instead an extension of the existing
289object system.
3c7278fb 290
e522431d 291Moose is built on top of L<Class::MOP>, which is a metaclass system
292for Perl 5. This means that Moose not only makes building normal
505c6fac 293Perl 5 objects better, but it also provides the power of metaclass
294programming.
e522431d 295
296=head2 What does Moose stand for??
297
298Moose doesn't stand for one thing in particular, however, if you
299want, here are a few of my favorites, feel free to contribute
300more :)
301
302=over 4
303
5569c072 304=item Make Other Object Systems Envious
e522431d 305
306=item Makes Object Orientation So Easy
307
5569c072 308=item Makes Object Orientation Spiffy- Er (sorry ingy)
505c6fac 309
5569c072 310=item Most Other Object Systems Emasculate
505c6fac 311
312=item My Overcraft Overfilled (with) Some Eels
313
314=item Moose Often Ovulate Sorta Early
315
505c6fac 316=item Many Overloaded Object Systems Exists
317
318=item Moose Offers Often Super Extensions
319
446e850f 320=item Meta Object Orientation Syntax Extensions
321
e522431d 322=back
3c7278fb 323
6ba6d68c 324=head1 BUILDING CLASSES WITH MOOSE
325
326Moose makes every attempt to provide as much convience during class
327construction/definition, but still stay out of your way if you want
328it to. Here are some of the features Moose provides:
329
330Unless specified with C<extends>, any class which uses Moose will
331inherit from L<Moose::Object>.
332
333Moose will also manage all attributes (including inherited ones) that
334are defined with C<has>. And assuming that you call C<new> which is
335inherited from L<Moose::Object>, then this includes properly initializing
336all instance slots, setting defaults where approprtiate and performing any
337type constraint checking or coercion.
338
79592a54 339For more details, see the ever expanding L<Moose::Cookbook>.
340
6ba6d68c 341=head1 EXPORTED FUNCTIONS
342
343Moose will export a number of functions into the class's namespace, which
344can then be used to set up the class. These functions all work directly
345on the current class.
346
347=over 4
348
349=item B<meta>
350
351This is a method which provides access to the current class's metaclass.
352
353=item B<extends (@superclasses)>
354
355This function will set the superclass(es) for the current class.
356
357This approach is recommended instead of C<use base>, because C<use base>
358actually C<push>es onto the class's C<@ISA>, whereas C<extends> will
359replace it. This is important to ensure that classes which do not have
360superclasses properly inherit from L<Moose::Object>.
361
e9ec68d6 362=item B<with ($role)>
363
76d37e5a 364This will apply a given C<$role> to the local class. Role support is
365currently very experimental, see L<Moose::Role> for more details.
e9ec68d6 366
6ba6d68c 367=item B<has ($name, %options)>
368
369This will install an attribute of a given C<$name> into the current class.
370The list of C<%options> are the same as those provided by both
371L<Class::MOP::Attribute> and L<Moose::Meta::Attribute>, in addition to a
372few convience ones provided by Moose which are listed below:
373
374=over 4
375
076c81ed 376=item I<is =E<gt> 'rw'|'ro'>
6ba6d68c 377
378The I<is> option accepts either I<rw> (for read/write) or I<ro> (for read
379only). These will create either a read/write accessor or a read-only
380accessor respectively, using the same name as the C<$name> of the attribute.
381
382If you need more control over how your accessors are named, you can use the
383I<reader>, I<writer> and I<accessor> options inherited from L<Moose::Meta::Attribute>.
384
076c81ed 385=item I<isa =E<gt> $type_name>
6ba6d68c 386
387The I<isa> option uses Moose's type constraint facilities to set up runtime
388type checking for this attribute. Moose will perform the checks during class
389construction, and within any accessors. The C<$type_name> argument must be a
390string. The string can be either a class name, or a type defined using
391Moose's type defintion features.
392
daea75c9 393=item I<coerce =E<gt> (1|0)>
394
395This will attempt to use coercion with the supplied type constraint to change
396the value passed into any accessors of constructors. You B<must> have supplied
397a type constraint in order for this to work. See L<Moose::Cookbook::Recipe5>
398for an example usage.
399
400=item I<does =E<gt> $role_name>
401
402This will accept the name of a role which the value stored in this attribute
403is expected to have consumed.
404
405=item I<required =E<gt> (1|0)>
406
407This marks the attribute as being required. This means a value must be supplied
408during class construction, and the attribute can never be set to C<undef> with
409an accessor.
410
411=item I<weak_ref =E<gt> (1|0)>
412
413This will tell the class to strore the value of this attribute as a weakened
414reference. If an attribute is a weakened reference, it can B<not> also be coerced.
415
416=item I<lazy =E<gt> (1|0)>
417
418This will tell the class to not create this slot until absolutely nessecary.
419If an attribute is marked as lazy it B<must> have a default supplied.
420
421=item I<trigger =E<gt> $code>
422
423The trigger option is a CODE reference which will be called after the value of
424the attribute is set. The CODE ref will be passed the instance itself, the
425updated value and the attribute meta-object (this is for more advanced fiddling
cce8198b 426and can typically be ignored in most cases). You can B<not> have a trigger on
427a read-only attribute.
daea75c9 428
6ba6d68c 429=back
430
076c81ed 431=item B<before $name|@names =E<gt> sub { ... }>
6ba6d68c 432
076c81ed 433=item B<after $name|@names =E<gt> sub { ... }>
6ba6d68c 434
076c81ed 435=item B<around $name|@names =E<gt> sub { ... }>
6ba6d68c 436
437This three items are syntactic sugar for the before, after and around method
438modifier features that L<Class::MOP> provides. More information on these can
439be found in the L<Class::MOP> documentation for now.
440
159da176 441=item B<super>
442
443The keyword C<super> is a noop when called outside of an C<override> method. In
444the context of an C<override> method, it will call the next most appropriate
445superclass method with the same arguments as the original method.
446
447=item B<override ($name, &sub)>
448
449An C<override> method, is a way of explictly saying "I am overriding this
450method from my superclass". You can call C<super> within this method, and
451it will work as expected. The same thing I<can> be accomplished with a normal
452method call and the C<SUPER::> pseudo-package, it is really your choice.
453
454=item B<inner>
455
456The keyword C<inner>, much like C<super>, is a no-op outside of the context of
457an C<augment> method. You can think of C<inner> as being the inverse of
458C<super>, the details of how C<inner> and C<augment> work is best described in
459the L<Moose::Cookbook>.
460
461=item B<augment ($name, &sub)>
462
463An C<augment> method, is a way of explictly saying "I am augmenting this
464method from my superclass". Once again, the details of how C<inner> and
465C<augment> work is best described in the L<Moose::Cookbook>.
466
6ba6d68c 467=item B<confess>
468
469This is the C<Carp::confess> function, and exported here beause I use it
470all the time. This feature may change in the future, so you have been warned.
471
472=item B<blessed>
473
474This is the C<Scalar::Uti::blessed> function, it is exported here beause I
475use it all the time. It is highly recommended that this is used instead of
476C<ref> anywhere you need to test for an object's class name.
477
478=back
479
05d9eaf6 480=head1 CAVEATS
481
482=over 4
483
484=item *
485
486It should be noted that C<super> and C<inner> can B<not> be used in the same
487method. However, they can be combined together with the same class hierarchy,
488see F<t/014_override_augment_inner_super.t> for an example.
489
490The reason that this is so is because C<super> is only valid within a method
491with the C<override> modifier, and C<inner> will never be valid within an
492C<override> method. In fact, C<augment> will skip over any C<override> methods
493when searching for it's appropriate C<inner>.
494
495This might seem like a restriction, but I am of the opinion that keeping these
496two features seperate (but interoperable) actually makes them easy to use since
497their behavior is then easier to predict. Time will tell if I am right or not.
498
499=back
500
5569c072 501=head1 ACKNOWLEDGEMENTS
502
503=over 4
504
54c189df 505=item I blame Sam Vilain for introducing me to the insanity that is meta-models.
5569c072 506
54c189df 507=item I blame Audrey Tang for then encouraging my meta-model habit in #perl6.
5569c072 508
076c81ed 509=item Without Yuval "nothingmuch" Kogman this module would not be possible,
54c189df 510and it certainly wouldn't have this name ;P
5569c072 511
512=item The basis of the TypeContraints module was Rob Kinyon's idea
513originally, I just ran with it.
514
076c81ed 515=item Thanks to mst & chansen and the whole #moose poose for all the
d46a48f3 516ideas/feature-requests/encouragement
517
5569c072 518=back
519
e90c03d0 520=head1 SEE ALSO
521
522=over 4
523
6ba6d68c 524=item L<Class::MOP> documentation
525
526=item The #moose channel on irc.perl.org
527
e90c03d0 528=item L<http://forum2.org/moose/>
529
159da176 530=item L<http://www.cs.utah.edu/plt/publications/oopsla04-gff.pdf>
531
532This paper (suggested by lbr on #moose) was what lead to the implementation
533of the C<super>/C<overrride> and C<inner>/C<augment> features. If you really
534want to understand this feature, I suggest you read this.
535
e90c03d0 536=back
537
fcd84ca9 538=head1 BUGS
539
540All complex software has bugs lurking in it, and this module is no
541exception. If you find a bug please either email me, or add the bug
542to cpan-RT.
543
fcd84ca9 544=head1 AUTHOR
545
546Stevan Little E<lt>stevan@iinteractive.comE<gt>
547
548=head1 COPYRIGHT AND LICENSE
549
550Copyright 2006 by Infinity Interactive, Inc.
551
552L<http://www.iinteractive.com>
553
554This library is free software; you can redistribute it and/or modify
555it under the same terms as Perl itself.
556
ddd0ec20 557=cut