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