tweaking a little here and there
[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
c1c2c3ed 14use Class::MOP::Immutable;
857f87a7 15
81c8a65b 16our $VERSION = '0.36';
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(
81c8a65b 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 },
81c8a65b 82 init_arg => 'package',
727919c5 83 ))
84);
85
a5e51f0b 86Class::MOP::Package->meta->add_attribute(
81c8a65b 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;
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 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 },
81c8a65b 173 init_arg => 'attributes',
727919c5 174 default => sub { {} }
175 ))
176);
177
351bd7d4 178Class::MOP::Class->meta->add_attribute(
81c8a65b 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(
81c8a65b 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 },
81c8a65b 214 init_arg => 'attribute_metaclass',
351bd7d4 215 default => 'Class::MOP::Attribute',
216 ))
217);
218
219Class::MOP::Class->meta->add_attribute(
81c8a65b 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 },
81c8a65b 227 init_arg => 'method_metaclass',
351bd7d4 228 default => 'Class::MOP::Method',
229 ))
230);
231
2bab2be6 232Class::MOP::Class->meta->add_attribute(
81c8a65b 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 },
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 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(
81c8a65b 399 Class::MOP::Attribute->new('%!modifier_table')
400);
401
402## --------------------------------------------------------
403## Class::MOP::Method::Accessor
404
405Class::MOP::Method::Accessor->meta->add_attribute(
406 Class::MOP::Attribute->new('$!attribute' => (
407 init_arg => 'attribute',
408 reader => {
409 'associated_attribute' => \&Class::MOP::Method::Accessor::associated_attribute
410 },
411 ))
412);
413
414Class::MOP::Method::Accessor->meta->add_attribute(
415 Class::MOP::Attribute->new('$!accessor_type' => (
416 init_arg => 'accessor_type',
417 reader => { 'accessor_type' => \&Class::MOP::Method::Accessor::accessor_type },
418 ))
419);
420
421Class::MOP::Method::Accessor->meta->add_attribute(
422 Class::MOP::Attribute->new('$!is_inline' => (
423 init_arg => 'is_inline',
424 reader => { 'is_inline' => \&Class::MOP::Method::Accessor::is_inline },
425 ))
426);
427
428## --------------------------------------------------------
429## Class::MOP::Method::Constructor
430
431Class::MOP::Method::Constructor->meta->add_attribute(
432 Class::MOP::Attribute->new('%!options' => (
433 init_arg => 'options',
434 reader => {
435 'options' => \&Class::MOP::Method::Constructor::options
436 },
437 ))
438);
439
440Class::MOP::Method::Constructor->meta->add_attribute(
8ea9d560 441 Class::MOP::Attribute->new('$!metaclass' => (
442 init_arg => 'metaclass',
81c8a65b 443 ))
b6164407 444);
445
446## --------------------------------------------------------
86482605 447## Class::MOP::Instance
448
449# NOTE:
450# these don't yet do much of anything, but are just
451# included for completeness
452
453Class::MOP::Instance->meta->add_attribute(
81c8a65b 454 Class::MOP::Attribute->new('$!meta')
86482605 455);
456
457Class::MOP::Instance->meta->add_attribute(
81c8a65b 458 Class::MOP::Attribute->new('@!slots')
86482605 459);
460
461## --------------------------------------------------------
f0480c45 462## Now close all the Class::MOP::* classes
4d47b77f 463
0b9372a2 464# NOTE:
465# we don't need to inline the
466# constructors or the accessors
467# this only lengthens the compile
468# time of the MOP, and gives us
469# no actual benefits.
470
471$_->meta->make_immutable(
472 inline_constructor => 0,
473 inline_accessors => 0,
474) for qw/
475 Class::MOP::Package
476 Class::MOP::Module
477 Class::MOP::Class
86482605 478
0b9372a2 479 Class::MOP::Attribute
480 Class::MOP::Method
481 Class::MOP::Instance
86482605 482
0b9372a2 483 Class::MOP::Object
484
ba38bf08 485 Class::MOP::Method::Accessor
81c8a65b 486 Class::MOP::Method::Constructor
487 Class::MOP::Method::Wrapped
0b9372a2 488/;
b6164407 489
94b19069 4901;
491
492__END__
493
494=pod
495
496=head1 NAME
497
498Class::MOP - A Meta Object Protocol for Perl 5
499
500=head1 SYNOPSIS
501
a2e85e6c 502 # ... This will come later, for now see
503 # the other SYNOPSIS for more information
94b19069 504
505=head1 DESCRIPTON
506
507This module is an attempt to create a meta object protocol for the
508Perl 5 object system. It makes no attempt to change the behavior or
509characteristics of the Perl 5 object system, only to create a
27e31eaf 510protocol for its manipulation and introspection.
94b19069 511
512That said, it does attempt to create the tools for building a rich
513set of extensions to the Perl 5 object system. Every attempt has been
514made for these tools to keep to the spirit of the Perl 5 object
515system that we all know and love.
516
40483095 517This documentation is admittedly sparse on details, as time permits
518I will try to improve them. For now, I suggest looking at the items
519listed in the L<SEE ALSO> section for more information. In particular
520the book "The Art of the Meta Object Protocol" was very influential
521in the development of this system.
522
bfe4d0fc 523=head2 What is a Meta Object Protocol?
524
525A meta object protocol is an API to an object system.
526
527To be more specific, it is a set of abstractions of the components of
528an object system (typically things like; classes, object, methods,
529object attributes, etc.). These abstractions can then be used to both
530inspect and manipulate the object system which they describe.
531
532It can be said that there are two MOPs for any object system; the
533implicit MOP, and the explicit MOP. The implicit MOP handles things
534like method dispatch or inheritance, which happen automatically as
535part of how the object system works. The explicit MOP typically
536handles the introspection/reflection features of the object system.
537All object systems have implicit MOPs, without one, they would not
538work. Explict MOPs however as less common, and depending on the
539language can vary from restrictive (Reflection in Java or C#) to
540wide open (CLOS is a perfect example).
541
e16da3e6 542=head2 Yet Another Class Builder!! Why?
543
544This is B<not> a class builder so much as it is a I<class builder
545B<builder>>. My intent is that an end user does not use this module
546directly, but instead this module is used by module authors to
547build extensions and features onto the Perl 5 object system.
548
94b19069 549=head2 Who is this module for?
550
551This module is specifically for anyone who has ever created or
552wanted to create a module for the Class:: namespace. The tools which
553this module will provide will hopefully make it easier to do more
554complex things with Perl 5 classes by removing such barriers as
555the need to hack the symbol tables, or understand the fine details
556of method dispatch.
557
bfe4d0fc 558=head2 What changes do I have to make to use this module?
559
2eb717d5 560This module was designed to be as unintrusive as possible. Many of
343203ee 561its features are accessible without B<any> change to your existsing
bfe4d0fc 562code at all. It is meant to be a compliment to your existing code and
2eb717d5 563not an intrusion on your code base. Unlike many other B<Class::>
a2e85e6c 564modules, this module B<does not> require you subclass it, or even that
565you C<use> it in within your module's package.
bfe4d0fc 566
2eb717d5 567The only features which requires additions to your code are the
568attribute handling and instance construction features, and these are
a2e85e6c 569both completely optional features. The only reason for this is because
2eb717d5 570Perl 5's object system does not actually have these features built
571in. More information about this feature can be found below.
bfe4d0fc 572
573=head2 A Note about Performance?
574
575It is a common misconception that explict MOPs are performance drains.
576But this is not a universal truth at all, it is an side-effect of
577specific implementations. For instance, using Java reflection is much
578slower because the JVM cannot take advantage of any compiler
579optimizations, and the JVM has to deal with much more runtime type
580information as well. Reflection in C# is marginally better as it was
581designed into the language and runtime (the CLR). In contrast, CLOS
582(the Common Lisp Object System) was built to support an explicit MOP,
583and so performance is tuned for it.
584
585This library in particular does it's absolute best to avoid putting
2eb717d5 586B<any> drain at all upon your code's performance. In fact, by itself
587it does nothing to affect your existing code. So you only pay for
588what you actually use.
bfe4d0fc 589
550d56db 590=head2 About Metaclass compatibility
591
592This module makes sure that all metaclasses created are both upwards
593and downwards compatible. The topic of metaclass compatibility is
594highly esoteric and is something only encountered when doing deep and
595involved metaclass hacking. There are two basic kinds of metaclass
596incompatibility; upwards and downwards.
597
598Upwards metaclass compatibility means that the metaclass of a
599given class is either the same as (or a subclass of) all of the
600class's ancestors.
601
602Downward metaclass compatibility means that the metaclasses of a
603given class's anscestors are all either the same as (or a subclass
604of) that metaclass.
605
606Here is a diagram showing a set of two classes (C<A> and C<B>) and
607two metaclasses (C<Meta::A> and C<Meta::B>) which have correct
608metaclass compatibility both upwards and downwards.
609
610 +---------+ +---------+
611 | Meta::A |<----| Meta::B | <....... (instance of )
612 +---------+ +---------+ <------- (inherits from)
613 ^ ^
614 : :
615 +---------+ +---------+
616 | A |<----| B |
617 +---------+ +---------+
618
619As I said this is a highly esoteric topic and one you will only run
620into if you do a lot of subclassing of B<Class::MOP::Class>. If you
621are interested in why this is an issue see the paper
622I<Uniform and safe metaclass composition> linked to in the
623L<SEE ALSO> section of this document.
624
aa448b16 625=head2 Using custom metaclasses
626
627Always use the metaclass pragma when using a custom metaclass, this
628will ensure the proper initialization order and not accidentely
629create an incorrect type of metaclass for you. This is a very rare
630problem, and one which can only occur if you are doing deep metaclass
631programming. So in other words, don't worry about it.
632
94b19069 633=head1 PROTOCOLS
634
635The protocol is divided into 3 main sub-protocols:
636
637=over 4
638
639=item The Class protocol
640
641This provides a means of manipulating and introspecting a Perl 5
642class. It handles all of symbol table hacking for you, and provides
643a rich set of methods that go beyond simple package introspection.
644
552e3d24 645See L<Class::MOP::Class> for more details.
646
94b19069 647=item The Attribute protocol
648
649This provides a consistent represenation for an attribute of a
650Perl 5 class. Since there are so many ways to create and handle
651atttributes in Perl 5 OO, this attempts to provide as much of a
652unified approach as possible, while giving the freedom and
653flexibility to subclass for specialization.
654
552e3d24 655See L<Class::MOP::Attribute> for more details.
656
94b19069 657=item The Method protocol
658
659This provides a means of manipulating and introspecting methods in
660the Perl 5 object system. As with attributes, there are many ways to
661approach this topic, so we try to keep it pretty basic, while still
662making it possible to extend the system in many ways.
663
552e3d24 664See L<Class::MOP::Method> for more details.
94b19069 665
666=back
667
be7677c7 668=head1 FUNCTIONS
669
670Class::MOP holds a cache of metaclasses, the following are functions
671(B<not methods>) which can be used to access that cache. It is not
672recommended that you mess with this, bad things could happen. But if
673you are brave and willing to risk it, go for it.
674
675=over 4
676
677=item B<get_all_metaclasses>
678
b9d9fc0b 679This will return an hash of all the metaclass instances that have
680been cached by B<Class::MOP::Class> keyed by the package name.
681
be7677c7 682=item B<get_all_metaclass_instances>
683
b9d9fc0b 684This will return an array of all the metaclass instances that have
685been cached by B<Class::MOP::Class>.
686
be7677c7 687=item B<get_all_metaclass_names>
688
b9d9fc0b 689This will return an array of all the metaclass names that have
690been cached by B<Class::MOP::Class>.
691
be7677c7 692=item B<get_metaclass_by_name ($name)>
693
694=item B<store_metaclass_by_name ($name, $meta)>
695
696=item B<weaken_metaclass ($name)>
697
698=item B<does_metaclass_exist ($name)>
699
700=item B<remove_metaclass_by_name ($name)>
701
702=back
703
552e3d24 704=head1 SEE ALSO
8b978dd5 705
552e3d24 706=head2 Books
8b978dd5 707
a2e85e6c 708There are very few books out on Meta Object Protocols and Metaclasses
709because it is such an esoteric topic. The following books are really
710the only ones I have found. If you know of any more, B<I<please>>
711email me and let me know, I would love to hear about them.
712
8b978dd5 713=over 4
714
552e3d24 715=item "The Art of the Meta Object Protocol"
8b978dd5 716
552e3d24 717=item "Advances in Object-Oriented Metalevel Architecture and Reflection"
8b978dd5 718
b51af7f9 719=item "Putting MetaClasses to Work"
720
a2e85e6c 721=item "Smalltalk: The Language"
722
94b19069 723=back
724
550d56db 725=head2 Papers
726
727=over 4
728
729=item Uniform and safe metaclass composition
730
731An excellent paper by the people who brought us the original Traits paper.
732This paper is on how Traits can be used to do safe metaclass composition,
733and offers an excellent introduction section which delves into the topic of
734metaclass compatibility.
735
736L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
737
738=item Safe Metaclass Programming
739
740This paper seems to precede the above paper, and propose a mix-in based
741approach as opposed to the Traits based approach. Both papers have similar
742information on the metaclass compatibility problem space.
743
744L<http://citeseer.ist.psu.edu/37617.html>
745
746=back
747
552e3d24 748=head2 Prior Art
8b978dd5 749
750=over 4
751
7184ca14 752=item The Perl 6 MetaModel work in the Pugs project
8b978dd5 753
754=over 4
755
552e3d24 756=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
8b978dd5 757
552e3d24 758=item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
8b978dd5 759
760=back
761
94b19069 762=back
763
f8dfcfb7 764=head2 Article
765
766=over 4
767
768=item CPAN Module Review of Class::MOP
769
770L<http://www.oreillynet.com/onlamp/blog/2006/06/cpan_module_review_classmop.html>
771
772=back
773
a2e85e6c 774=head1 SIMILAR MODULES
775
776As I have said above, this module is a class-builder-builder, so it is
777not the same thing as modules like L<Class::Accessor> and
778L<Class::MethodMaker>. That being said there are very few modules on CPAN
779with similar goals to this module. The one I have found which is most
550d56db 780like this module is L<Class::Meta>, although it's philosophy and the MOP it
781creates are very different from this modules.
94b19069 782
a2e85e6c 783=head1 BUGS
784
785All complex software has bugs lurking in it, and this module is no
786exception. If you find a bug please either email me, or add the bug
787to cpan-RT.
788
22286063 789=head1 CODE COVERAGE
790
791I use L<Devel::Cover> to test the code coverage of my tests, below is the
792L<Devel::Cover> report on this module's test suite.
793
794 ---------------------------- ------ ------ ------ ------ ------ ------ ------
795 File stmt bran cond sub pod time total
796 ---------------------------- ------ ------ ------ ------ ------ ------ ------
cf3fa89c 797 Class/MOP.pm 97.7 100.0 88.9 94.7 100.0 3.2 96.6
798 Class/MOP/Attribute.pm 75.5 77.9 82.4 88.3 100.0 4.0 81.5
799 Class/MOP/Class.pm 96.9 88.8 72.1 98.2 100.0 35.8 91.4
800 Class/MOP/Class/Immutable.pm 88.2 60.0 n/a 95.5 100.0 0.5 84.6
801 Class/MOP/Instance.pm 86.4 75.0 33.3 86.2 100.0 1.2 87.5
802 Class/MOP/Method.pm 97.5 75.0 61.5 80.6 100.0 12.7 89.7
803 Class/MOP/Module.pm 100.0 n/a 55.6 100.0 100.0 0.1 90.7
804 Class/MOP/Object.pm 73.3 n/a 20.0 80.0 100.0 0.1 66.7
805 Class/MOP/Package.pm 94.6 71.7 33.3 100.0 100.0 42.2 87.0
806 metaclass.pm 100.0 100.0 83.3 100.0 n/a 0.2 97.7
22286063 807 ---------------------------- ------ ------ ------ ------ ------ ------ ------
cf3fa89c 808 Total 91.3 80.4 69.8 91.9 100.0 100.0 88.1
22286063 809 ---------------------------- ------ ------ ------ ------ ------ ------ ------
810
a2e85e6c 811=head1 ACKNOWLEDGEMENTS
812
813=over 4
814
b9d9fc0b 815=item Rob Kinyon
a2e85e6c 816
817Thanks to Rob for actually getting the development of this module kick-started.
818
819=back
820
1a09d9cc 821=head1 AUTHORS
94b19069 822
a2e85e6c 823Stevan Little E<lt>stevan@iinteractive.comE<gt>
552e3d24 824
1a09d9cc 825Yuval Kogman E<lt>nothingmuch@woobling.comE<gt>
826
94b19069 827=head1 COPYRIGHT AND LICENSE
828
829Copyright 2006 by Infinity Interactive, Inc.
830
831L<http://www.iinteractive.com>
832
833This library is free software; you can redistribute it and/or modify
834it under the same terms as Perl itself.
835
836=cut