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