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