Lots of doc updates
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
CommitLineData
94b19069 1
2package Class::MOP;
3
4use strict;
5use warnings;
6
727919c5 7use Carp 'confess';
be7677c7 8use Scalar::Util 'weaken';
8b978dd5 9
2eb717d5 10use Class::MOP::Class;
11use Class::MOP::Attribute;
12use Class::MOP::Method;
13
c23184fc 14use Class::MOP::Immutable;
857f87a7 15
9363ea89 16our $VERSION = '0.37';
f0480c45 17our $AUTHORITY = 'cpan:STEVAN';
94b19069 18
be7677c7 19{
20 # Metaclasses are singletons, so we cache them here.
21 # there is no need to worry about destruction though
22 # because they should die only when the program dies.
23 # After all, do package definitions even get reaped?
24 my %METAS;
25
26 # means of accessing all the metaclasses that have
27 # been initialized thus far (for mugwumps obj browser)
28 sub get_all_metaclasses { %METAS }
29 sub get_all_metaclass_instances { values %METAS }
30 sub get_all_metaclass_names { keys %METAS }
31 sub get_metaclass_by_name { $METAS{$_[0]} }
32 sub store_metaclass_by_name { $METAS{$_[0]} = $_[1] }
33 sub weaken_metaclass { weaken($METAS{$_[0]}) }
34 sub does_metaclass_exist { exists $METAS{$_[0]} && defined $METAS{$_[0]} }
35 sub remove_metaclass_by_name { $METAS{$_[0]} = undef }
36
37 # NOTE:
38 # We only cache metaclasses, meaning instances of
39 # Class::MOP::Class. We do not cache instance of
40 # Class::MOP::Package or Class::MOP::Module. Mostly
41 # because I don't yet see a good reason to do so.
42}
43
aa448b16 44## ----------------------------------------------------------------------------
45## Setting up our environment ...
46## ----------------------------------------------------------------------------
47## Class::MOP needs to have a few things in the global perl environment so
48## that it can operate effectively. Those things are done here.
49## ----------------------------------------------------------------------------
50
3bf7644b 51# ... nothing yet actually ;)
8b978dd5 52
b51af7f9 53## ----------------------------------------------------------------------------
54## Bootstrapping
55## ----------------------------------------------------------------------------
56## The code below here is to bootstrap our MOP with itself. This is also
57## sometimes called "tying the knot". By doing this, we make it much easier
58## to extend the MOP through subclassing and such since now you can use the
59## MOP itself to extend itself.
60##
61## Yes, I know, thats weird and insane, but it's a good thing, trust me :)
62## ----------------------------------------------------------------------------
727919c5 63
64# We need to add in the meta-attributes here so that
65# any subclass of Class::MOP::* will be able to
66# inherit them using &construct_instance
67
f0480c45 68## --------------------------------------------------------
6d5355c3 69## Class::MOP::Package
727919c5 70
6d5355c3 71Class::MOP::Package->meta->add_attribute(
c23184fc 72 Class::MOP::Attribute->new('$!package' => (
b880e0de 73 reader => {
74 # NOTE: we need to do this in order
75 # for the instance meta-object to
76 # not fall into meta-circular death
ce2ae40f 77 #
78 # we just alias the original method
79 # rather than re-produce it here
80 'name' => \&Class::MOP::Package::name
b880e0de 81 },
c23184fc 82 init_arg => 'package',
727919c5 83 ))
84);
85
a5e51f0b 86Class::MOP::Package->meta->add_attribute(
c23184fc 87 Class::MOP::Attribute->new('%!namespace' => (
a5e51f0b 88 reader => {
56dcfc1a 89 # NOTE:
ce2ae40f 90 # we just alias the original method
91 # rather than re-produce it here
92 'namespace' => \&Class::MOP::Package::namespace
a5e51f0b 93 },
94 # NOTE:
95 # protect this from silliness
a2ee6c61 96 init_arg => '!............( DO NOT DO THIS )............!',
c4260b45 97 default => sub { \undef }
a5e51f0b 98 ))
99);
100
9d6dce77 101# NOTE:
102# use the metaclass to construct the meta-package
103# which is a superclass of the metaclass itself :P
104Class::MOP::Package->meta->add_method('initialize' => sub {
105 my $class = shift;
106 my $package_name = shift;
c23184fc 107 $class->meta->new_object('package' => $package_name, @_);
9d6dce77 108});
109
f0480c45 110## --------------------------------------------------------
111## Class::MOP::Module
112
113# NOTE:
114# yeah this is kind of stretching things a bit,
115# but truthfully the version should be an attribute
116# of the Module, the weirdness comes from having to
117# stick to Perl 5 convention and store it in the
118# $VERSION package variable. Basically if you just
119# squint at it, it will look how you want it to look.
120# Either as a package variable, or as a attribute of
121# the metaclass, isn't abstraction great :)
122
123Class::MOP::Module->meta->add_attribute(
c23184fc 124 Class::MOP::Attribute->new('$!version' => (
f0480c45 125 reader => {
ce2ae40f 126 # NOTE:
127 # we just alias the original method
128 # rather than re-produce it here
129 'version' => \&Class::MOP::Module::version
f0480c45 130 },
131 # NOTE:
132 # protect this from silliness
133 init_arg => '!............( DO NOT DO THIS )............!',
c4260b45 134 default => sub { \undef }
f0480c45 135 ))
136);
137
138# NOTE:
139# By following the same conventions as version here,
140# we are opening up the possibility that people can
141# use the $AUTHORITY in non-Class::MOP modules as
142# well.
143
144Class::MOP::Module->meta->add_attribute(
c23184fc 145 Class::MOP::Attribute->new('$!authority' => (
f0480c45 146 reader => {
ce2ae40f 147 # NOTE:
148 # we just alias the original method
149 # rather than re-produce it here
150 'authority' => \&Class::MOP::Module::authority
f0480c45 151 },
152 # NOTE:
153 # protect this from silliness
154 init_arg => '!............( DO NOT DO THIS )............!',
c4260b45 155 default => sub { \undef }
f0480c45 156 ))
157);
158
159## --------------------------------------------------------
6d5355c3 160## Class::MOP::Class
161
727919c5 162Class::MOP::Class->meta->add_attribute(
c23184fc 163 Class::MOP::Attribute->new('%!attributes' => (
f7259199 164 reader => {
165 # NOTE: we need to do this in order
166 # for the instance meta-object to
ce2ae40f 167 # not fall into meta-circular death
168 #
169 # we just alias the original method
170 # rather than re-produce it here
171 'get_attribute_map' => \&Class::MOP::Class::get_attribute_map
f7259199 172 },
c23184fc 173 init_arg => 'attributes',
727919c5 174 default => sub { {} }
175 ))
176);
177
351bd7d4 178Class::MOP::Class->meta->add_attribute(
c23184fc 179 Class::MOP::Attribute->new('%!methods' => (
180 init_arg => 'methods',
92330ee2 181 reader => {
ce2ae40f 182 # NOTE:
183 # we just alias the original method
184 # rather than re-produce it here
185 'get_method_map' => \&Class::MOP::Class::get_method_map
92330ee2 186 },
7855ddba 187 default => sub { {} }
c4260b45 188 ))
189);
190
191Class::MOP::Class->meta->add_attribute(
c23184fc 192 Class::MOP::Attribute->new('@!superclasses' => (
193 accessor => {
194 # NOTE:
195 # we just alias the original method
196 # rather than re-produce it here
197 'superclasses' => \&Class::MOP::Class::superclasses
198 },
199 # NOTE:
200 # protect this from silliness
201 init_arg => '!............( DO NOT DO THIS )............!',
202 default => sub { \undef }
203 ))
204);
205
206Class::MOP::Class->meta->add_attribute(
207 Class::MOP::Attribute->new('$!attribute_metaclass' => (
6d2118a4 208 reader => {
209 # NOTE:
210 # we just alias the original method
211 # rather than re-produce it here
212 'attribute_metaclass' => \&Class::MOP::Class::attribute_metaclass
213 },
c23184fc 214 init_arg => 'attribute_metaclass',
351bd7d4 215 default => 'Class::MOP::Attribute',
216 ))
217);
218
219Class::MOP::Class->meta->add_attribute(
c23184fc 220 Class::MOP::Attribute->new('$!method_metaclass' => (
6d2118a4 221 reader => {
222 # NOTE:
223 # we just alias the original method
224 # rather than re-produce it here
225 'method_metaclass' => \&Class::MOP::Class::method_metaclass
226 },
c23184fc 227 init_arg => 'method_metaclass',
351bd7d4 228 default => 'Class::MOP::Method',
229 ))
230);
231
2bab2be6 232Class::MOP::Class->meta->add_attribute(
c23184fc 233 Class::MOP::Attribute->new('$!instance_metaclass' => (
b880e0de 234 reader => {
235 # NOTE: we need to do this in order
236 # for the instance meta-object to
ce2ae40f 237 # not fall into meta-circular death
238 #
239 # we just alias the original method
240 # rather than re-produce it here
241 'instance_metaclass' => \&Class::MOP::Class::instance_metaclass
b880e0de 242 },
c23184fc 243 init_arg => 'instance_metaclass',
2bab2be6 244 default => 'Class::MOP::Instance',
245 ))
246);
247
9d6dce77 248# NOTE:
249# we don't actually need to tie the knot with
250# Class::MOP::Class here, it is actually handled
251# within Class::MOP::Class itself in the
252# construct_class_instance method.
253
f0480c45 254## --------------------------------------------------------
727919c5 255## Class::MOP::Attribute
256
7b31baf4 257Class::MOP::Attribute->meta->add_attribute(
c23184fc 258 Class::MOP::Attribute->new('$!name' => (
259 init_arg => 'name',
260 reader => {
b880e0de 261 # NOTE: we need to do this in order
262 # for the instance meta-object to
ce2ae40f 263 # not fall into meta-circular death
264 #
265 # we just alias the original method
266 # rather than re-produce it here
267 'name' => \&Class::MOP::Attribute::name
b880e0de 268 }
7b31baf4 269 ))
270);
271
272Class::MOP::Attribute->meta->add_attribute(
c23184fc 273 Class::MOP::Attribute->new('$!associated_class' => (
274 init_arg => 'associated_class',
275 reader => {
b880e0de 276 # NOTE: we need to do this in order
277 # for the instance meta-object to
ce2ae40f 278 # not fall into meta-circular death
279 #
280 # we just alias the original method
281 # rather than re-produce it here
282 'associated_class' => \&Class::MOP::Attribute::associated_class
b880e0de 283 }
7b31baf4 284 ))
285);
286
287Class::MOP::Attribute->meta->add_attribute(
c23184fc 288 Class::MOP::Attribute->new('$!accessor' => (
289 init_arg => 'accessor',
6d2118a4 290 reader => { 'accessor' => \&Class::MOP::Attribute::accessor },
291 predicate => { 'has_accessor' => \&Class::MOP::Attribute::has_accessor },
7b31baf4 292 ))
293);
294
295Class::MOP::Attribute->meta->add_attribute(
c23184fc 296 Class::MOP::Attribute->new('$!reader' => (
297 init_arg => 'reader',
6d2118a4 298 reader => { 'reader' => \&Class::MOP::Attribute::reader },
299 predicate => { 'has_reader' => \&Class::MOP::Attribute::has_reader },
7b31baf4 300 ))
301);
302
303Class::MOP::Attribute->meta->add_attribute(
c23184fc 304 Class::MOP::Attribute->new('$!writer' => (
305 init_arg => 'writer',
6d2118a4 306 reader => { 'writer' => \&Class::MOP::Attribute::writer },
307 predicate => { 'has_writer' => \&Class::MOP::Attribute::has_writer },
7b31baf4 308 ))
309);
310
311Class::MOP::Attribute->meta->add_attribute(
c23184fc 312 Class::MOP::Attribute->new('$!predicate' => (
313 init_arg => 'predicate',
6d2118a4 314 reader => { 'predicate' => \&Class::MOP::Attribute::predicate },
315 predicate => { 'has_predicate' => \&Class::MOP::Attribute::has_predicate },
7b31baf4 316 ))
317);
318
319Class::MOP::Attribute->meta->add_attribute(
c23184fc 320 Class::MOP::Attribute->new('$!clearer' => (
321 init_arg => 'clearer',
6d2118a4 322 reader => { 'clearer' => \&Class::MOP::Attribute::clearer },
323 predicate => { 'has_clearer' => \&Class::MOP::Attribute::has_clearer },
7d28758b 324 ))
325);
326
327Class::MOP::Attribute->meta->add_attribute(
c23184fc 328 Class::MOP::Attribute->new('$!init_arg' => (
329 init_arg => 'init_arg',
6d2118a4 330 reader => { 'init_arg' => \&Class::MOP::Attribute::init_arg },
331 predicate => { 'has_init_arg' => \&Class::MOP::Attribute::has_init_arg },
7b31baf4 332 ))
333);
334
335Class::MOP::Attribute->meta->add_attribute(
c23184fc 336 Class::MOP::Attribute->new('$!default' => (
337 init_arg => 'default',
7b31baf4 338 # default has a custom 'reader' method ...
6d2118a4 339 predicate => { 'has_default' => \&Class::MOP::Attribute::has_default },
7b31baf4 340 ))
341);
342
3545c727 343Class::MOP::Attribute->meta->add_attribute(
c23184fc 344 Class::MOP::Attribute->new('@!associated_methods' => (
345 init_arg => 'associated_methods',
346 reader => { 'associated_methods' => \&Class::MOP::Attribute::associated_methods },
347 default => sub { [] }
3545c727 348 ))
349);
727919c5 350
351# NOTE: (meta-circularity)
352# This should be one of the last things done
353# it will "tie the knot" with Class::MOP::Attribute
354# so that it uses the attributes meta-objects
355# to construct itself.
356Class::MOP::Attribute->meta->add_method('new' => sub {
357 my $class = shift;
358 my $name = shift;
359 my %options = @_;
360
361 (defined $name && $name)
362 || confess "You must provide a name for the attribute";
5659d76e 363 $options{init_arg} = $name
364 if not exists $options{init_arg};
148b4697 365
366 (Class::MOP::Attribute::is_default_a_coderef(\%options))
367 || confess("References are not allowed as default values, you must ".
368 "wrap then in a CODE reference (ex: sub { [] } and not [])")
369 if exists $options{default} && ref $options{default};
651955fb 370
5659d76e 371 # return the new object
372 $class->meta->new_object(name => $name, %options);
373});
374
375Class::MOP::Attribute->meta->add_method('clone' => sub {
a740253a 376 my $self = shift;
a27ae83f 377 $self->meta->clone_object($self, @_);
727919c5 378});
379
f0480c45 380## --------------------------------------------------------
b6164407 381## Class::MOP::Method
382
383Class::MOP::Method->meta->add_attribute(
c23184fc 384 Class::MOP::Attribute->new('&!body' => (
385 init_arg => 'body',
386 reader => { 'body' => \&Class::MOP::Method::body },
b6164407 387 ))
388);
389
390## --------------------------------------------------------
391## Class::MOP::Method::Wrapped
392
393# NOTE:
394# the way this item is initialized, this
395# really does not follow the standard
396# practices of attributes, but we put
397# it here for completeness
398Class::MOP::Method::Wrapped->meta->add_attribute(
c23184fc 399 Class::MOP::Attribute->new('%!modifier_table')
b6164407 400);
401
402## --------------------------------------------------------
d90b42a6 403## Class::MOP::Method::Accessor
404
405Class::MOP::Method::Accessor->meta->add_attribute(
c23184fc 406 Class::MOP::Attribute->new('$!attribute' => (
407 init_arg => 'attribute',
408 reader => {
d90b42a6 409 'associated_attribute' => \&Class::MOP::Method::Accessor::associated_attribute
410 },
411 ))
412);
413
414Class::MOP::Method::Accessor->meta->add_attribute(
c23184fc 415 Class::MOP::Attribute->new('$!accessor_type' => (
416 init_arg => 'accessor_type',
417 reader => { 'accessor_type' => \&Class::MOP::Method::Accessor::accessor_type },
d90b42a6 418 ))
419);
420
421Class::MOP::Method::Accessor->meta->add_attribute(
c23184fc 422 Class::MOP::Attribute->new('$!is_inline' => (
423 init_arg => 'is_inline',
424 reader => { 'is_inline' => \&Class::MOP::Method::Accessor::is_inline },
d90b42a6 425 ))
426);
427
428## --------------------------------------------------------
429## Class::MOP::Method::Constructor
430
431Class::MOP::Method::Constructor->meta->add_attribute(
c23184fc 432 Class::MOP::Attribute->new('%!options' => (
433 init_arg => 'options',
434 reader => {
d90b42a6 435 'options' => \&Class::MOP::Method::Constructor::options
436 },
437 ))
438);
439
440Class::MOP::Method::Constructor->meta->add_attribute(
c23184fc 441 Class::MOP::Attribute->new('$!associated_metaclass' => (
442 init_arg => 'metaclass',
443 reader => {
444 'associated_metaclass' => \&Class::MOP::Method::Constructor::associated_metaclass
445 },
d90b42a6 446 ))
447);
448
449## --------------------------------------------------------
86482605 450## Class::MOP::Instance
451
452# NOTE:
453# these don't yet do much of anything, but are just
454# included for completeness
455
456Class::MOP::Instance->meta->add_attribute(
c23184fc 457 Class::MOP::Attribute->new('$!meta')
86482605 458);
459
460Class::MOP::Instance->meta->add_attribute(
c23184fc 461 Class::MOP::Attribute->new('@!slots')
86482605 462);
463
464## --------------------------------------------------------
f0480c45 465## Now close all the Class::MOP::* classes
4d47b77f 466
0b9372a2 467# NOTE:
468# we don't need to inline the
469# constructors or the accessors
470# this only lengthens the compile
471# time of the MOP, and gives us
472# no actual benefits.
473
474$_->meta->make_immutable(
475 inline_constructor => 0,
476 inline_accessors => 0,
477) for qw/
478 Class::MOP::Package
479 Class::MOP::Module
480 Class::MOP::Class
86482605 481
0b9372a2 482 Class::MOP::Attribute
483 Class::MOP::Method
484 Class::MOP::Instance
86482605 485
0b9372a2 486 Class::MOP::Object
487
ba38bf08 488 Class::MOP::Method::Accessor
d90b42a6 489 Class::MOP::Method::Constructor
490 Class::MOP::Method::Wrapped
0b9372a2 491/;
b6164407 492
94b19069 4931;
494
495__END__
496
497=pod
498
499=head1 NAME
500
501Class::MOP - A Meta Object Protocol for Perl 5
502
503=head1 SYNOPSIS
504
a2e85e6c 505 # ... This will come later, for now see
506 # the other SYNOPSIS for more information
94b19069 507
508=head1 DESCRIPTON
509
510This module is an attempt to create a meta object protocol for the
511Perl 5 object system. It makes no attempt to change the behavior or
512characteristics of the Perl 5 object system, only to create a
27e31eaf 513protocol for its manipulation and introspection.
94b19069 514
515That said, it does attempt to create the tools for building a rich
516set of extensions to the Perl 5 object system. Every attempt has been
517made for these tools to keep to the spirit of the Perl 5 object
518system that we all know and love.
519
40483095 520This documentation is admittedly sparse on details, as time permits
521I will try to improve them. For now, I suggest looking at the items
522listed in the L<SEE ALSO> section for more information. In particular
523the book "The Art of the Meta Object Protocol" was very influential
524in the development of this system.
525
bfe4d0fc 526=head2 What is a Meta Object Protocol?
527
528A meta object protocol is an API to an object system.
529
530To be more specific, it is a set of abstractions of the components of
531an object system (typically things like; classes, object, methods,
532object attributes, etc.). These abstractions can then be used to both
533inspect and manipulate the object system which they describe.
534
535It can be said that there are two MOPs for any object system; the
536implicit MOP, and the explicit MOP. The implicit MOP handles things
537like method dispatch or inheritance, which happen automatically as
538part of how the object system works. The explicit MOP typically
539handles the introspection/reflection features of the object system.
540All object systems have implicit MOPs, without one, they would not
541work. Explict MOPs however as less common, and depending on the
542language can vary from restrictive (Reflection in Java or C#) to
543wide open (CLOS is a perfect example).
544
e16da3e6 545=head2 Yet Another Class Builder!! Why?
546
547This is B<not> a class builder so much as it is a I<class builder
548B<builder>>. My intent is that an end user does not use this module
549directly, but instead this module is used by module authors to
550build extensions and features onto the Perl 5 object system.
551
94b19069 552=head2 Who is this module for?
553
554This module is specifically for anyone who has ever created or
555wanted to create a module for the Class:: namespace. The tools which
556this module will provide will hopefully make it easier to do more
557complex things with Perl 5 classes by removing such barriers as
558the need to hack the symbol tables, or understand the fine details
559of method dispatch.
560
bfe4d0fc 561=head2 What changes do I have to make to use this module?
562
2eb717d5 563This module was designed to be as unintrusive as possible. Many of
343203ee 564its features are accessible without B<any> change to your existsing
bfe4d0fc 565code at all. It is meant to be a compliment to your existing code and
2eb717d5 566not an intrusion on your code base. Unlike many other B<Class::>
a2e85e6c 567modules, this module B<does not> require you subclass it, or even that
568you C<use> it in within your module's package.
bfe4d0fc 569
2eb717d5 570The only features which requires additions to your code are the
571attribute handling and instance construction features, and these are
a2e85e6c 572both completely optional features. The only reason for this is because
2eb717d5 573Perl 5's object system does not actually have these features built
574in. More information about this feature can be found below.
bfe4d0fc 575
576=head2 A Note about Performance?
577
578It is a common misconception that explict MOPs are performance drains.
579But this is not a universal truth at all, it is an side-effect of
580specific implementations. For instance, using Java reflection is much
581slower because the JVM cannot take advantage of any compiler
582optimizations, and the JVM has to deal with much more runtime type
583information as well. Reflection in C# is marginally better as it was
584designed into the language and runtime (the CLR). In contrast, CLOS
585(the Common Lisp Object System) was built to support an explicit MOP,
586and so performance is tuned for it.
587
588This library in particular does it's absolute best to avoid putting
2eb717d5 589B<any> drain at all upon your code's performance. In fact, by itself
590it does nothing to affect your existing code. So you only pay for
591what you actually use.
bfe4d0fc 592
550d56db 593=head2 About Metaclass compatibility
594
595This module makes sure that all metaclasses created are both upwards
596and downwards compatible. The topic of metaclass compatibility is
597highly esoteric and is something only encountered when doing deep and
598involved metaclass hacking. There are two basic kinds of metaclass
599incompatibility; upwards and downwards.
600
601Upwards metaclass compatibility means that the metaclass of a
602given class is either the same as (or a subclass of) all of the
603class's ancestors.
604
605Downward metaclass compatibility means that the metaclasses of a
606given class's anscestors are all either the same as (or a subclass
607of) that metaclass.
608
609Here is a diagram showing a set of two classes (C<A> and C<B>) and
610two metaclasses (C<Meta::A> and C<Meta::B>) which have correct
611metaclass compatibility both upwards and downwards.
612
613 +---------+ +---------+
614 | Meta::A |<----| Meta::B | <....... (instance of )
615 +---------+ +---------+ <------- (inherits from)
616 ^ ^
617 : :
618 +---------+ +---------+
619 | A |<----| B |
620 +---------+ +---------+
621
622As I said this is a highly esoteric topic and one you will only run
623into if you do a lot of subclassing of B<Class::MOP::Class>. If you
624are interested in why this is an issue see the paper
625I<Uniform and safe metaclass composition> linked to in the
626L<SEE ALSO> section of this document.
627
aa448b16 628=head2 Using custom metaclasses
629
630Always use the metaclass pragma when using a custom metaclass, this
631will ensure the proper initialization order and not accidentely
632create an incorrect type of metaclass for you. This is a very rare
633problem, and one which can only occur if you are doing deep metaclass
634programming. So in other words, don't worry about it.
635
94b19069 636=head1 PROTOCOLS
637
638The protocol is divided into 3 main sub-protocols:
639
640=over 4
641
642=item The Class protocol
643
644This provides a means of manipulating and introspecting a Perl 5
645class. It handles all of symbol table hacking for you, and provides
646a rich set of methods that go beyond simple package introspection.
647
552e3d24 648See L<Class::MOP::Class> for more details.
649
94b19069 650=item The Attribute protocol
651
652This provides a consistent represenation for an attribute of a
653Perl 5 class. Since there are so many ways to create and handle
654atttributes in Perl 5 OO, this attempts to provide as much of a
655unified approach as possible, while giving the freedom and
656flexibility to subclass for specialization.
657
552e3d24 658See L<Class::MOP::Attribute> for more details.
659
94b19069 660=item The Method protocol
661
662This provides a means of manipulating and introspecting methods in
663the Perl 5 object system. As with attributes, there are many ways to
664approach this topic, so we try to keep it pretty basic, while still
665making it possible to extend the system in many ways.
666
552e3d24 667See L<Class::MOP::Method> for more details.
94b19069 668
669=back
670
be7677c7 671=head1 FUNCTIONS
672
673Class::MOP holds a cache of metaclasses, the following are functions
674(B<not methods>) which can be used to access that cache. It is not
675recommended that you mess with this, bad things could happen. But if
676you are brave and willing to risk it, go for it.
677
678=over 4
679
680=item B<get_all_metaclasses>
681
b9d9fc0b 682This will return an hash of all the metaclass instances that have
683been cached by B<Class::MOP::Class> keyed by the package name.
684
be7677c7 685=item B<get_all_metaclass_instances>
686
b9d9fc0b 687This will return an array of all the metaclass instances that have
688been cached by B<Class::MOP::Class>.
689
be7677c7 690=item B<get_all_metaclass_names>
691
b9d9fc0b 692This will return an array of all the metaclass names that have
693been cached by B<Class::MOP::Class>.
694
be7677c7 695=item B<get_metaclass_by_name ($name)>
696
697=item B<store_metaclass_by_name ($name, $meta)>
698
699=item B<weaken_metaclass ($name)>
700
701=item B<does_metaclass_exist ($name)>
702
703=item B<remove_metaclass_by_name ($name)>
704
705=back
706
552e3d24 707=head1 SEE ALSO
8b978dd5 708
552e3d24 709=head2 Books
8b978dd5 710
a2e85e6c 711There are very few books out on Meta Object Protocols and Metaclasses
712because it is such an esoteric topic. The following books are really
713the only ones I have found. If you know of any more, B<I<please>>
714email me and let me know, I would love to hear about them.
715
8b978dd5 716=over 4
717
552e3d24 718=item "The Art of the Meta Object Protocol"
8b978dd5 719
552e3d24 720=item "Advances in Object-Oriented Metalevel Architecture and Reflection"
8b978dd5 721
b51af7f9 722=item "Putting MetaClasses to Work"
723
a2e85e6c 724=item "Smalltalk: The Language"
725
94b19069 726=back
727
550d56db 728=head2 Papers
729
730=over 4
731
732=item Uniform and safe metaclass composition
733
734An excellent paper by the people who brought us the original Traits paper.
735This paper is on how Traits can be used to do safe metaclass composition,
736and offers an excellent introduction section which delves into the topic of
737metaclass compatibility.
738
739L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
740
741=item Safe Metaclass Programming
742
743This paper seems to precede the above paper, and propose a mix-in based
744approach as opposed to the Traits based approach. Both papers have similar
745information on the metaclass compatibility problem space.
746
747L<http://citeseer.ist.psu.edu/37617.html>
748
749=back
750
552e3d24 751=head2 Prior Art
8b978dd5 752
753=over 4
754
7184ca14 755=item The Perl 6 MetaModel work in the Pugs project
8b978dd5 756
757=over 4
758
552e3d24 759=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
8b978dd5 760
552e3d24 761=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
8b978dd5 762
763=back
764
94b19069 765=back
766
f8dfcfb7 767=head2 Article
768
769=over 4
770
771=item CPAN Module Review of Class::MOP
772
773L<http://www.oreillynet.com/onlamp/blog/2006/06/cpan_module_review_classmop.html>
774
775=back
776
a2e85e6c 777=head1 SIMILAR MODULES
778
779As I have said above, this module is a class-builder-builder, so it is
780not the same thing as modules like L<Class::Accessor> and
781L<Class::MethodMaker>. That being said there are very few modules on CPAN
782with similar goals to this module. The one I have found which is most
550d56db 783like this module is L<Class::Meta>, although it's philosophy and the MOP it
784creates are very different from this modules.
94b19069 785
a2e85e6c 786=head1 BUGS
787
788All complex software has bugs lurking in it, and this module is no
789exception. If you find a bug please either email me, or add the bug
790to cpan-RT.
791
22286063 792=head1 CODE COVERAGE
793
794I use L<Devel::Cover> to test the code coverage of my tests, below is the
795L<Devel::Cover> report on this module's test suite.
796
797 ---------------------------- ------ ------ ------ ------ ------ ------ ------
798 File stmt bran cond sub pod time total
799 ---------------------------- ------ ------ ------ ------ ------ ------ ------
cf3fa89c 800 Class/MOP.pm 97.7 100.0 88.9 94.7 100.0 3.2 96.6
801 Class/MOP/Attribute.pm 75.5 77.9 82.4 88.3 100.0 4.0 81.5
802 Class/MOP/Class.pm 96.9 88.8 72.1 98.2 100.0 35.8 91.4
803 Class/MOP/Class/Immutable.pm 88.2 60.0 n/a 95.5 100.0 0.5 84.6
804 Class/MOP/Instance.pm 86.4 75.0 33.3 86.2 100.0 1.2 87.5
805 Class/MOP/Method.pm 97.5 75.0 61.5 80.6 100.0 12.7 89.7
806 Class/MOP/Module.pm 100.0 n/a 55.6 100.0 100.0 0.1 90.7
807 Class/MOP/Object.pm 73.3 n/a 20.0 80.0 100.0 0.1 66.7
808 Class/MOP/Package.pm 94.6 71.7 33.3 100.0 100.0 42.2 87.0
809 metaclass.pm 100.0 100.0 83.3 100.0 n/a 0.2 97.7
22286063 810 ---------------------------- ------ ------ ------ ------ ------ ------ ------
cf3fa89c 811 Total 91.3 80.4 69.8 91.9 100.0 100.0 88.1
22286063 812 ---------------------------- ------ ------ ------ ------ ------ ------ ------
813
a2e85e6c 814=head1 ACKNOWLEDGEMENTS
815
816=over 4
817
b9d9fc0b 818=item Rob Kinyon
a2e85e6c 819
820Thanks to Rob for actually getting the development of this module kick-started.
821
822=back
823
1a09d9cc 824=head1 AUTHORS
94b19069 825
a2e85e6c 826Stevan Little E<lt>stevan@iinteractive.comE<gt>
552e3d24 827
1a09d9cc 828Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
829
94b19069 830=head1 COPYRIGHT AND LICENSE
831
2367814a 832Copyright 2006, 2007 by Infinity Interactive, Inc.
94b19069 833
834L<http://www.iinteractive.com>
835
836This library is free software; you can redistribute it and/or modify
837it under the same terms as Perl itself.
838
839=cut