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