fixing version numbers and writing the changelog
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
CommitLineData
94b19069 1
2package Class::MOP;
3
4use strict;
5use warnings;
6
727919c5 7use Carp 'confess';
aa448b16 8use Scalar::Util ();
8b978dd5 9
2eb717d5 10use Class::MOP::Class;
11use Class::MOP::Attribute;
12use Class::MOP::Method;
13
857f87a7 14use Class::MOP::Class::Immutable;
15
9ca19585 16our $VERSION = '0.32';
94b19069 17
aa448b16 18## ----------------------------------------------------------------------------
19## Setting up our environment ...
20## ----------------------------------------------------------------------------
21## Class::MOP needs to have a few things in the global perl environment so
22## that it can operate effectively. Those things are done here.
23## ----------------------------------------------------------------------------
24
3bf7644b 25# ... nothing yet actually ;)
8b978dd5 26
b51af7f9 27## ----------------------------------------------------------------------------
28## Bootstrapping
29## ----------------------------------------------------------------------------
30## The code below here is to bootstrap our MOP with itself. This is also
31## sometimes called "tying the knot". By doing this, we make it much easier
32## to extend the MOP through subclassing and such since now you can use the
33## MOP itself to extend itself.
34##
35## Yes, I know, thats weird and insane, but it's a good thing, trust me :)
36## ----------------------------------------------------------------------------
727919c5 37
38# We need to add in the meta-attributes here so that
39# any subclass of Class::MOP::* will be able to
40# inherit them using &construct_instance
41
6d5355c3 42## Class::MOP::Package
727919c5 43
6d5355c3 44Class::MOP::Package->meta->add_attribute(
351bd7d4 45 Class::MOP::Attribute->new('$:package' => (
b880e0de 46 reader => {
47 # NOTE: we need to do this in order
48 # for the instance meta-object to
49 # not fall into meta-circular death
50 'name' => sub { (shift)->{'$:package'} }
51 },
7b31baf4 52 init_arg => ':package',
727919c5 53 ))
54);
55
a5e51f0b 56Class::MOP::Package->meta->add_attribute(
57 Class::MOP::Attribute->new('%:namespace' => (
58 reader => {
59 'namespace' => sub { (shift)->{'%:namespace'} }
60 },
61 default => sub {
62 my ($class) = @_;
63 no strict 'refs';
64 return \%{$class->name . '::'};
65 },
66 # NOTE:
67 # protect this from silliness
a2ee6c61 68 init_arg => '!............( DO NOT DO THIS )............!',
a5e51f0b 69 ))
70);
71
9d6dce77 72# NOTE:
73# use the metaclass to construct the meta-package
74# which is a superclass of the metaclass itself :P
75Class::MOP::Package->meta->add_method('initialize' => sub {
76 my $class = shift;
77 my $package_name = shift;
78 $class->meta->new_object(':package' => $package_name, @_);
79});
80
6d5355c3 81## Class::MOP::Class
82
727919c5 83Class::MOP::Class->meta->add_attribute(
351bd7d4 84 Class::MOP::Attribute->new('%:attributes' => (
f7259199 85 reader => {
86 # NOTE: we need to do this in order
87 # for the instance meta-object to
88 # not fall into meta-circular death
89 'get_attribute_map' => sub { (shift)->{'%:attributes'} }
90 },
351bd7d4 91 init_arg => ':attributes',
727919c5 92 default => sub { {} }
93 ))
94);
95
351bd7d4 96Class::MOP::Class->meta->add_attribute(
97 Class::MOP::Attribute->new('$:attribute_metaclass' => (
7b31baf4 98 reader => 'attribute_metaclass',
351bd7d4 99 init_arg => ':attribute_metaclass',
100 default => 'Class::MOP::Attribute',
101 ))
102);
103
104Class::MOP::Class->meta->add_attribute(
105 Class::MOP::Attribute->new('$:method_metaclass' => (
7b31baf4 106 reader => 'method_metaclass',
351bd7d4 107 init_arg => ':method_metaclass',
108 default => 'Class::MOP::Method',
109 ))
110);
111
2bab2be6 112Class::MOP::Class->meta->add_attribute(
113 Class::MOP::Attribute->new('$:instance_metaclass' => (
b880e0de 114 reader => {
115 # NOTE: we need to do this in order
116 # for the instance meta-object to
117 # not fall into meta-circular death
118 'instance_metaclass' => sub { (shift)->{'$:instance_metaclass'} }
119 },
2bab2be6 120 init_arg => ':instance_metaclass',
121 default => 'Class::MOP::Instance',
122 ))
123);
124
9d6dce77 125# NOTE:
126# we don't actually need to tie the knot with
127# Class::MOP::Class here, it is actually handled
128# within Class::MOP::Class itself in the
129# construct_class_instance method.
130
727919c5 131## Class::MOP::Attribute
132
7b31baf4 133Class::MOP::Attribute->meta->add_attribute(
134 Class::MOP::Attribute->new('name' => (
b880e0de 135 reader => {
136 # NOTE: we need to do this in order
137 # for the instance meta-object to
138 # not fall into meta-circular death
139 'name' => sub { (shift)->{name} }
140 }
7b31baf4 141 ))
142);
143
144Class::MOP::Attribute->meta->add_attribute(
145 Class::MOP::Attribute->new('associated_class' => (
b880e0de 146 reader => {
147 # NOTE: we need to do this in order
148 # for the instance meta-object to
149 # not fall into meta-circular death
150 'associated_class' => sub { (shift)->{associated_class} }
151 }
7b31baf4 152 ))
153);
154
155Class::MOP::Attribute->meta->add_attribute(
156 Class::MOP::Attribute->new('accessor' => (
157 reader => 'accessor',
158 predicate => 'has_accessor',
159 ))
160);
161
162Class::MOP::Attribute->meta->add_attribute(
163 Class::MOP::Attribute->new('reader' => (
164 reader => 'reader',
165 predicate => 'has_reader',
166 ))
167);
168
169Class::MOP::Attribute->meta->add_attribute(
170 Class::MOP::Attribute->new('writer' => (
171 reader => 'writer',
172 predicate => 'has_writer',
173 ))
174);
175
176Class::MOP::Attribute->meta->add_attribute(
177 Class::MOP::Attribute->new('predicate' => (
178 reader => 'predicate',
179 predicate => 'has_predicate',
180 ))
181);
182
183Class::MOP::Attribute->meta->add_attribute(
7d28758b 184 Class::MOP::Attribute->new('clearer' => (
185 reader => 'clearer',
186 predicate => 'has_clearer',
187 ))
188);
189
190Class::MOP::Attribute->meta->add_attribute(
7b31baf4 191 Class::MOP::Attribute->new('init_arg' => (
192 reader => 'init_arg',
193 predicate => 'has_init_arg',
194 ))
195);
196
197Class::MOP::Attribute->meta->add_attribute(
198 Class::MOP::Attribute->new('default' => (
199 # default has a custom 'reader' method ...
200 predicate => 'has_default',
201 ))
202);
203
727919c5 204
205# NOTE: (meta-circularity)
206# This should be one of the last things done
207# it will "tie the knot" with Class::MOP::Attribute
208# so that it uses the attributes meta-objects
209# to construct itself.
210Class::MOP::Attribute->meta->add_method('new' => sub {
211 my $class = shift;
212 my $name = shift;
213 my %options = @_;
214
215 (defined $name && $name)
216 || confess "You must provide a name for the attribute";
5659d76e 217 $options{init_arg} = $name
218 if not exists $options{init_arg};
651955fb 219
5659d76e 220 # return the new object
221 $class->meta->new_object(name => $name, %options);
222});
223
224Class::MOP::Attribute->meta->add_method('clone' => sub {
a740253a 225 my $self = shift;
a27ae83f 226 $self->meta->clone_object($self, @_);
727919c5 227});
228
4d47b77f 229## Try and close Class::MOP::*
230
231Class::MOP::Package ->meta->make_immutable(inline_constructor => 0);
232Class::MOP::Module ->meta->make_immutable(inline_constructor => 0);
233Class::MOP::Class ->meta->make_immutable(inline_constructor => 0);
234Class::MOP::Attribute->meta->make_immutable(inline_constructor => 0);
235Class::MOP::Method ->meta->make_immutable(inline_constructor => 0);
236Class::MOP::Instance ->meta->make_immutable(inline_constructor => 0);
237
238
94b19069 2391;
240
241__END__
242
243=pod
244
245=head1 NAME
246
247Class::MOP - A Meta Object Protocol for Perl 5
248
249=head1 SYNOPSIS
250
a2e85e6c 251 # ... This will come later, for now see
252 # the other SYNOPSIS for more information
94b19069 253
254=head1 DESCRIPTON
255
256This module is an attempt to create a meta object protocol for the
257Perl 5 object system. It makes no attempt to change the behavior or
258characteristics of the Perl 5 object system, only to create a
27e31eaf 259protocol for its manipulation and introspection.
94b19069 260
261That said, it does attempt to create the tools for building a rich
262set of extensions to the Perl 5 object system. Every attempt has been
263made for these tools to keep to the spirit of the Perl 5 object
264system that we all know and love.
265
40483095 266This documentation is admittedly sparse on details, as time permits
267I will try to improve them. For now, I suggest looking at the items
268listed in the L<SEE ALSO> section for more information. In particular
269the book "The Art of the Meta Object Protocol" was very influential
270in the development of this system.
271
bfe4d0fc 272=head2 What is a Meta Object Protocol?
273
274A meta object protocol is an API to an object system.
275
276To be more specific, it is a set of abstractions of the components of
277an object system (typically things like; classes, object, methods,
278object attributes, etc.). These abstractions can then be used to both
279inspect and manipulate the object system which they describe.
280
281It can be said that there are two MOPs for any object system; the
282implicit MOP, and the explicit MOP. The implicit MOP handles things
283like method dispatch or inheritance, which happen automatically as
284part of how the object system works. The explicit MOP typically
285handles the introspection/reflection features of the object system.
286All object systems have implicit MOPs, without one, they would not
287work. Explict MOPs however as less common, and depending on the
288language can vary from restrictive (Reflection in Java or C#) to
289wide open (CLOS is a perfect example).
290
e16da3e6 291=head2 Yet Another Class Builder!! Why?
292
293This is B<not> a class builder so much as it is a I<class builder
294B<builder>>. My intent is that an end user does not use this module
295directly, but instead this module is used by module authors to
296build extensions and features onto the Perl 5 object system.
297
94b19069 298=head2 Who is this module for?
299
300This module is specifically for anyone who has ever created or
301wanted to create a module for the Class:: namespace. The tools which
302this module will provide will hopefully make it easier to do more
303complex things with Perl 5 classes by removing such barriers as
304the need to hack the symbol tables, or understand the fine details
305of method dispatch.
306
bfe4d0fc 307=head2 What changes do I have to make to use this module?
308
2eb717d5 309This module was designed to be as unintrusive as possible. Many of
343203ee 310its features are accessible without B<any> change to your existsing
bfe4d0fc 311code at all. It is meant to be a compliment to your existing code and
2eb717d5 312not an intrusion on your code base. Unlike many other B<Class::>
a2e85e6c 313modules, this module B<does not> require you subclass it, or even that
314you C<use> it in within your module's package.
bfe4d0fc 315
2eb717d5 316The only features which requires additions to your code are the
317attribute handling and instance construction features, and these are
a2e85e6c 318both completely optional features. The only reason for this is because
2eb717d5 319Perl 5's object system does not actually have these features built
320in. More information about this feature can be found below.
bfe4d0fc 321
322=head2 A Note about Performance?
323
324It is a common misconception that explict MOPs are performance drains.
325But this is not a universal truth at all, it is an side-effect of
326specific implementations. For instance, using Java reflection is much
327slower because the JVM cannot take advantage of any compiler
328optimizations, and the JVM has to deal with much more runtime type
329information as well. Reflection in C# is marginally better as it was
330designed into the language and runtime (the CLR). In contrast, CLOS
331(the Common Lisp Object System) was built to support an explicit MOP,
332and so performance is tuned for it.
333
334This library in particular does it's absolute best to avoid putting
2eb717d5 335B<any> drain at all upon your code's performance. In fact, by itself
336it does nothing to affect your existing code. So you only pay for
337what you actually use.
bfe4d0fc 338
550d56db 339=head2 About Metaclass compatibility
340
341This module makes sure that all metaclasses created are both upwards
342and downwards compatible. The topic of metaclass compatibility is
343highly esoteric and is something only encountered when doing deep and
344involved metaclass hacking. There are two basic kinds of metaclass
345incompatibility; upwards and downwards.
346
347Upwards metaclass compatibility means that the metaclass of a
348given class is either the same as (or a subclass of) all of the
349class's ancestors.
350
351Downward metaclass compatibility means that the metaclasses of a
352given class's anscestors are all either the same as (or a subclass
353of) that metaclass.
354
355Here is a diagram showing a set of two classes (C<A> and C<B>) and
356two metaclasses (C<Meta::A> and C<Meta::B>) which have correct
357metaclass compatibility both upwards and downwards.
358
359 +---------+ +---------+
360 | Meta::A |<----| Meta::B | <....... (instance of )
361 +---------+ +---------+ <------- (inherits from)
362 ^ ^
363 : :
364 +---------+ +---------+
365 | A |<----| B |
366 +---------+ +---------+
367
368As I said this is a highly esoteric topic and one you will only run
369into if you do a lot of subclassing of B<Class::MOP::Class>. If you
370are interested in why this is an issue see the paper
371I<Uniform and safe metaclass composition> linked to in the
372L<SEE ALSO> section of this document.
373
aa448b16 374=head2 Using custom metaclasses
375
376Always use the metaclass pragma when using a custom metaclass, this
377will ensure the proper initialization order and not accidentely
378create an incorrect type of metaclass for you. This is a very rare
379problem, and one which can only occur if you are doing deep metaclass
380programming. So in other words, don't worry about it.
381
94b19069 382=head1 PROTOCOLS
383
384The protocol is divided into 3 main sub-protocols:
385
386=over 4
387
388=item The Class protocol
389
390This provides a means of manipulating and introspecting a Perl 5
391class. It handles all of symbol table hacking for you, and provides
392a rich set of methods that go beyond simple package introspection.
393
552e3d24 394See L<Class::MOP::Class> for more details.
395
94b19069 396=item The Attribute protocol
397
398This provides a consistent represenation for an attribute of a
399Perl 5 class. Since there are so many ways to create and handle
400atttributes in Perl 5 OO, this attempts to provide as much of a
401unified approach as possible, while giving the freedom and
402flexibility to subclass for specialization.
403
552e3d24 404See L<Class::MOP::Attribute> for more details.
405
94b19069 406=item The Method protocol
407
408This provides a means of manipulating and introspecting methods in
409the Perl 5 object system. As with attributes, there are many ways to
410approach this topic, so we try to keep it pretty basic, while still
411making it possible to extend the system in many ways.
412
552e3d24 413See L<Class::MOP::Method> for more details.
94b19069 414
415=back
416
552e3d24 417=head1 SEE ALSO
8b978dd5 418
552e3d24 419=head2 Books
8b978dd5 420
a2e85e6c 421There are very few books out on Meta Object Protocols and Metaclasses
422because it is such an esoteric topic. The following books are really
423the only ones I have found. If you know of any more, B<I<please>>
424email me and let me know, I would love to hear about them.
425
8b978dd5 426=over 4
427
552e3d24 428=item "The Art of the Meta Object Protocol"
8b978dd5 429
552e3d24 430=item "Advances in Object-Oriented Metalevel Architecture and Reflection"
8b978dd5 431
b51af7f9 432=item "Putting MetaClasses to Work"
433
a2e85e6c 434=item "Smalltalk: The Language"
435
94b19069 436=back
437
550d56db 438=head2 Papers
439
440=over 4
441
442=item Uniform and safe metaclass composition
443
444An excellent paper by the people who brought us the original Traits paper.
445This paper is on how Traits can be used to do safe metaclass composition,
446and offers an excellent introduction section which delves into the topic of
447metaclass compatibility.
448
449L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
450
451=item Safe Metaclass Programming
452
453This paper seems to precede the above paper, and propose a mix-in based
454approach as opposed to the Traits based approach. Both papers have similar
455information on the metaclass compatibility problem space.
456
457L<http://citeseer.ist.psu.edu/37617.html>
458
459=back
460
552e3d24 461=head2 Prior Art
8b978dd5 462
463=over 4
464
7184ca14 465=item The Perl 6 MetaModel work in the Pugs project
8b978dd5 466
467=over 4
468
552e3d24 469=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
8b978dd5 470
552e3d24 471=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
8b978dd5 472
473=back
474
94b19069 475=back
476
a2e85e6c 477=head1 SIMILAR MODULES
478
479As I have said above, this module is a class-builder-builder, so it is
480not the same thing as modules like L<Class::Accessor> and
481L<Class::MethodMaker>. That being said there are very few modules on CPAN
482with similar goals to this module. The one I have found which is most
550d56db 483like this module is L<Class::Meta>, although it's philosophy and the MOP it
484creates are very different from this modules.
94b19069 485
a2e85e6c 486=head1 BUGS
487
488All complex software has bugs lurking in it, and this module is no
489exception. If you find a bug please either email me, or add the bug
490to cpan-RT.
491
22286063 492=head1 CODE COVERAGE
493
494I use L<Devel::Cover> to test the code coverage of my tests, below is the
495L<Devel::Cover> report on this module's test suite.
496
497 ---------------------------- ------ ------ ------ ------ ------ ------ ------
498 File stmt bran cond sub pod time total
499 ---------------------------- ------ ------ ------ ------ ------ ------ ------
cdfaa4cc 500 Class/MOP.pm 100.0 100.0 100.0 100.0 n/a 19.8 100.0
501 Class/MOP/Attribute.pm 100.0 100.0 91.7 61.2 100.0 14.3 87.9
502 Class/MOP/Class.pm 97.6 91.3 77.3 98.4 100.0 56.4 93.2
503 Class/MOP/Instance.pm 91.1 75.0 33.3 91.7 100.0 6.8 90.7
504 Class/MOP/Method.pm 97.6 60.0 52.9 76.9 100.0 1.6 82.6
505 metaclass.pm 100.0 100.0 83.3 100.0 n/a 1.0 97.7
22286063 506 ---------------------------- ------ ------ ------ ------ ------ ------ ------
cdfaa4cc 507 Total 97.5 88.5 75.5 82.8 100.0 100.0 91.2
22286063 508 ---------------------------- ------ ------ ------ ------ ------ ------ ------
509
a2e85e6c 510=head1 ACKNOWLEDGEMENTS
511
512=over 4
513
514=item Rob Kinyon E<lt>rob@iinteractive.comE<gt>
515
516Thanks to Rob for actually getting the development of this module kick-started.
517
518=back
519
1a09d9cc 520=head1 AUTHORS
94b19069 521
a2e85e6c 522Stevan Little E<lt>stevan@iinteractive.comE<gt>
552e3d24 523
1a09d9cc 524Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
525
94b19069 526=head1 COPYRIGHT AND LICENSE
527
528Copyright 2006 by Infinity Interactive, Inc.
529
530L<http://www.iinteractive.com>
531
532This library is free software; you can redistribute it and/or modify
533it under the same terms as Perl itself.
534
535=cut