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