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