10 use Scalar::Util 'weaken';
12 use Sub::Identify 'get_code_info';
18 Sub::Name->import(qw(subname));
20 } or eval 'sub subname { $_[1] }';
22 # this is either part of core or set up appropriately by MRO::Compat
23 *check_package_cache_flag = \&mro::get_pkg_gen;
26 require Devel::GlobalDestruction;
27 Devel::GlobalDestruction->import("in_global_destruction");
29 } or *in_global_destruction = sub () { '' };
33 use Class::MOP::Class;
34 use Class::MOP::Attribute;
35 use Class::MOP::Method;
37 use Class::MOP::Immutable;
40 *IS_RUNNING_ON_5_10 = ($] < 5.009_005)
44 *HAVE_ISAREV = defined(&mro::get_isarev)
49 our $VERSION = '0.64_01';
50 $VERSION = eval $VERSION;
51 our $AUTHORITY = 'cpan:STEVAN';
53 # after that everything is loaded, if we're allowed try to load faster XS
54 # versions of various things
55 unless ($ENV{CLASS_MOP_NO_XS}) {
60 __PACKAGE__->XSLoader::load($VERSION);
65 die $e if $e && $e !~ /object version|loadable object/;
69 # Metaclasses are singletons, so we cache them here.
70 # there is no need to worry about destruction though
71 # because they should die only when the program dies.
72 # After all, do package definitions even get reaped?
75 # means of accessing all the metaclasses that have
76 # been initialized thus far (for mugwumps obj browser)
77 sub get_all_metaclasses { %METAS }
78 sub get_all_metaclass_instances { values %METAS }
79 sub get_all_metaclass_names { keys %METAS }
80 sub get_metaclass_by_name { $METAS{$_[0]} }
81 sub store_metaclass_by_name { $METAS{$_[0]} = $_[1] }
82 sub weaken_metaclass { weaken($METAS{$_[0]}) }
83 sub does_metaclass_exist { exists $METAS{$_[0]} && defined $METAS{$_[0]} }
84 sub remove_metaclass_by_name { $METAS{$_[0]} = undef }
87 # We only cache metaclasses, meaning instances of
88 # Class::MOP::Class. We do not cache instance of
89 # Class::MOP::Package or Class::MOP::Module. Mostly
90 # because I don't yet see a good reason to do so.
96 if (ref($class) || !defined($class) || !length($class)) {
97 my $display = defined($class) ? $class : 'undef';
98 confess "Invalid class name ($display)";
101 # if the class is not already loaded in the symbol table..
102 unless (is_class_loaded($class)) {
104 my $file = $class . '.pm';
106 my $e = do { local $@; eval { require($file) }; $@ };
107 confess "Could not load class ($class) because : $e" if $e;
110 # initialize a metaclass if necessary
111 unless (does_metaclass_exist($class)) {
112 my $e = do { local $@; eval { Class::MOP::Class->initialize($class) }; $@ };
113 confess "Could not initialize class ($class) because : $e" if $e;
116 return get_metaclass_by_name($class) if defined wantarray;
119 sub is_class_loaded {
122 return 0 if ref($class) || !defined($class) || !length($class);
124 # walk the symbol table tree to avoid autovififying
125 # \*{${main::}{"Foo::"}} == \*main::Foo::
128 foreach my $part (split('::', $class)) {
129 return 0 unless exists ${$$pack}{"${part}::"};
130 $pack = \*{${$$pack}{"${part}::"}};
133 # check for $VERSION or @ISA
134 return 1 if exists ${$$pack}{VERSION}
135 && defined *{${$$pack}{VERSION}}{SCALAR};
136 return 1 if exists ${$$pack}{ISA}
137 && defined *{${$$pack}{ISA}}{ARRAY};
139 # check for any method
140 foreach ( keys %{$$pack} ) {
141 next if substr($_, -2, 2) eq '::';
143 my $glob = ${$$pack}{$_} || next;
146 if ( IS_RUNNING_ON_5_10 ) {
147 return 1 if ref $glob eq 'SCALAR';
150 return 1 if defined *{$glob}{CODE};
158 ## ----------------------------------------------------------------------------
159 ## Setting up our environment ...
160 ## ----------------------------------------------------------------------------
161 ## Class::MOP needs to have a few things in the global perl environment so
162 ## that it can operate effectively. Those things are done here.
163 ## ----------------------------------------------------------------------------
165 # ... nothing yet actually ;)
167 ## ----------------------------------------------------------------------------
169 ## ----------------------------------------------------------------------------
170 ## The code below here is to bootstrap our MOP with itself. This is also
171 ## sometimes called "tying the knot". By doing this, we make it much easier
172 ## to extend the MOP through subclassing and such since now you can use the
173 ## MOP itself to extend itself.
175 ## Yes, I know, thats weird and insane, but it's a good thing, trust me :)
176 ## ----------------------------------------------------------------------------
178 # We need to add in the meta-attributes here so that
179 # any subclass of Class::MOP::* will be able to
180 # inherit them using &construct_instance
182 ## --------------------------------------------------------
183 ## Class::MOP::Package
185 Class::MOP::Package->meta->add_attribute(
186 Class::MOP::Attribute->new('package' => (
188 # NOTE: we need to do this in order
189 # for the instance meta-object to
190 # not fall into meta-circular death
192 # we just alias the original method
193 # rather than re-produce it here
194 'name' => \&Class::MOP::Package::name
199 Class::MOP::Package->meta->add_attribute(
200 Class::MOP::Attribute->new('namespace' => (
203 # we just alias the original method
204 # rather than re-produce it here
205 'namespace' => \&Class::MOP::Package::namespace
208 default => sub { \undef }
212 ## --------------------------------------------------------
213 ## Class::MOP::Module
216 # yeah this is kind of stretching things a bit,
217 # but truthfully the version should be an attribute
218 # of the Module, the weirdness comes from having to
219 # stick to Perl 5 convention and store it in the
220 # $VERSION package variable. Basically if you just
221 # squint at it, it will look how you want it to look.
222 # Either as a package variable, or as a attribute of
223 # the metaclass, isn't abstraction great :)
225 Class::MOP::Module->meta->add_attribute(
226 Class::MOP::Attribute->new('version' => (
229 # we just alias the original method
230 # rather than re-produce it here
231 'version' => \&Class::MOP::Module::version
234 default => sub { \undef }
239 # By following the same conventions as version here,
240 # we are opening up the possibility that people can
241 # use the $AUTHORITY in non-Class::MOP modules as
244 Class::MOP::Module->meta->add_attribute(
245 Class::MOP::Attribute->new('authority' => (
248 # we just alias the original method
249 # rather than re-produce it here
250 'authority' => \&Class::MOP::Module::authority
253 default => sub { \undef }
257 ## --------------------------------------------------------
260 Class::MOP::Class->meta->add_attribute(
261 Class::MOP::Attribute->new('attributes' => (
263 # NOTE: we need to do this in order
264 # for the instance meta-object to
265 # not fall into meta-circular death
267 # we just alias the original method
268 # rather than re-produce it here
269 'get_attribute_map' => \&Class::MOP::Class::get_attribute_map
271 default => sub { {} }
275 Class::MOP::Class->meta->add_attribute(
276 Class::MOP::Attribute->new('methods' => (
279 # we just alias the original method
280 # rather than re-produce it here
281 'get_method_map' => \&Class::MOP::Class::get_method_map
283 default => sub { {} }
287 Class::MOP::Class->meta->add_attribute(
288 Class::MOP::Attribute->new('superclasses' => (
291 # we just alias the original method
292 # rather than re-produce it here
293 'superclasses' => \&Class::MOP::Class::superclasses
296 default => sub { \undef }
300 Class::MOP::Class->meta->add_attribute(
301 Class::MOP::Attribute->new('attribute_metaclass' => (
304 # we just alias the original method
305 # rather than re-produce it here
306 'attribute_metaclass' => \&Class::MOP::Class::attribute_metaclass
308 default => 'Class::MOP::Attribute',
312 Class::MOP::Class->meta->add_attribute(
313 Class::MOP::Attribute->new('method_metaclass' => (
316 # we just alias the original method
317 # rather than re-produce it here
318 'method_metaclass' => \&Class::MOP::Class::method_metaclass
320 default => 'Class::MOP::Method',
324 Class::MOP::Class->meta->add_attribute(
325 Class::MOP::Attribute->new('instance_metaclass' => (
327 # NOTE: we need to do this in order
328 # for the instance meta-object to
329 # not fall into meta-circular death
331 # we just alias the original method
332 # rather than re-produce it here
333 'instance_metaclass' => \&Class::MOP::Class::instance_metaclass
335 default => 'Class::MOP::Instance',
340 # we don't actually need to tie the knot with
341 # Class::MOP::Class here, it is actually handled
342 # within Class::MOP::Class itself in the
343 # construct_class_instance method.
345 ## --------------------------------------------------------
346 ## Class::MOP::Attribute
348 Class::MOP::Attribute->meta->add_attribute(
349 Class::MOP::Attribute->new('name' => (
351 # NOTE: we need to do this in order
352 # for the instance meta-object to
353 # not fall into meta-circular death
355 # we just alias the original method
356 # rather than re-produce it here
357 'name' => \&Class::MOP::Attribute::name
362 Class::MOP::Attribute->meta->add_attribute(
363 Class::MOP::Attribute->new('associated_class' => (
365 # NOTE: we need to do this in order
366 # for the instance meta-object to
367 # not fall into meta-circular death
369 # we just alias the original method
370 # rather than re-produce it here
371 'associated_class' => \&Class::MOP::Attribute::associated_class
376 Class::MOP::Attribute->meta->add_attribute(
377 Class::MOP::Attribute->new('accessor' => (
378 reader => { 'accessor' => \&Class::MOP::Attribute::accessor },
379 predicate => { 'has_accessor' => \&Class::MOP::Attribute::has_accessor },
383 Class::MOP::Attribute->meta->add_attribute(
384 Class::MOP::Attribute->new('reader' => (
385 reader => { 'reader' => \&Class::MOP::Attribute::reader },
386 predicate => { 'has_reader' => \&Class::MOP::Attribute::has_reader },
390 Class::MOP::Attribute->meta->add_attribute(
391 Class::MOP::Attribute->new('initializer' => (
392 reader => { 'initializer' => \&Class::MOP::Attribute::initializer },
393 predicate => { 'has_initializer' => \&Class::MOP::Attribute::has_initializer },
397 Class::MOP::Attribute->meta->add_attribute(
398 Class::MOP::Attribute->new('writer' => (
399 reader => { 'writer' => \&Class::MOP::Attribute::writer },
400 predicate => { 'has_writer' => \&Class::MOP::Attribute::has_writer },
404 Class::MOP::Attribute->meta->add_attribute(
405 Class::MOP::Attribute->new('predicate' => (
406 reader => { 'predicate' => \&Class::MOP::Attribute::predicate },
407 predicate => { 'has_predicate' => \&Class::MOP::Attribute::has_predicate },
411 Class::MOP::Attribute->meta->add_attribute(
412 Class::MOP::Attribute->new('clearer' => (
413 reader => { 'clearer' => \&Class::MOP::Attribute::clearer },
414 predicate => { 'has_clearer' => \&Class::MOP::Attribute::has_clearer },
418 Class::MOP::Attribute->meta->add_attribute(
419 Class::MOP::Attribute->new('builder' => (
420 reader => { 'builder' => \&Class::MOP::Attribute::builder },
421 predicate => { 'has_builder' => \&Class::MOP::Attribute::has_builder },
425 Class::MOP::Attribute->meta->add_attribute(
426 Class::MOP::Attribute->new('init_arg' => (
427 reader => { 'init_arg' => \&Class::MOP::Attribute::init_arg },
428 predicate => { 'has_init_arg' => \&Class::MOP::Attribute::has_init_arg },
432 Class::MOP::Attribute->meta->add_attribute(
433 Class::MOP::Attribute->new('default' => (
434 # default has a custom 'reader' method ...
435 predicate => { 'has_default' => \&Class::MOP::Attribute::has_default },
439 Class::MOP::Attribute->meta->add_attribute(
440 Class::MOP::Attribute->new('associated_methods' => (
441 reader => { 'associated_methods' => \&Class::MOP::Attribute::associated_methods },
442 default => sub { [] }
446 Class::MOP::Attribute->meta->add_method('clone' => sub {
448 $self->meta->clone_object($self, @_);
451 ## --------------------------------------------------------
452 ## Class::MOP::Method
453 Class::MOP::Method->meta->add_attribute(
454 Class::MOP::Attribute->new('body' => (
455 reader => { 'body' => \&Class::MOP::Method::body },
459 Class::MOP::Method->meta->add_attribute(
460 Class::MOP::Attribute->new('associated_metaclass' => (
461 reader => { 'associated_metaclass' => \&Class::MOP::Method::associated_metaclass },
465 Class::MOP::Method->meta->add_attribute(
466 Class::MOP::Attribute->new('package_name' => (
467 reader => { 'package_name' => \&Class::MOP::Method::package_name },
471 Class::MOP::Method->meta->add_attribute(
472 Class::MOP::Attribute->new('name' => (
473 reader => { 'name' => \&Class::MOP::Method::name },
477 Class::MOP::Method->meta->add_method('clone' => sub {
479 $self->meta->clone_object($self, @_);
482 ## --------------------------------------------------------
483 ## Class::MOP::Method::Wrapped
486 # the way this item is initialized, this
487 # really does not follow the standard
488 # practices of attributes, but we put
489 # it here for completeness
490 Class::MOP::Method::Wrapped->meta->add_attribute(
491 Class::MOP::Attribute->new('modifier_table')
494 ## --------------------------------------------------------
495 ## Class::MOP::Method::Generated
497 Class::MOP::Method::Generated->meta->add_attribute(
498 Class::MOP::Attribute->new('is_inline' => (
499 reader => { 'is_inline' => \&Class::MOP::Method::Generated::is_inline },
504 ## --------------------------------------------------------
505 ## Class::MOP::Method::Accessor
507 Class::MOP::Method::Accessor->meta->add_attribute(
508 Class::MOP::Attribute->new('attribute' => (
510 'associated_attribute' => \&Class::MOP::Method::Accessor::associated_attribute
515 Class::MOP::Method::Accessor->meta->add_attribute(
516 Class::MOP::Attribute->new('accessor_type' => (
517 reader => { 'accessor_type' => \&Class::MOP::Method::Accessor::accessor_type },
521 ## --------------------------------------------------------
522 ## Class::MOP::Method::Constructor
524 Class::MOP::Method::Constructor->meta->add_attribute(
525 Class::MOP::Attribute->new('options' => (
527 'options' => \&Class::MOP::Method::Constructor::options
529 default => sub { +{} }
533 Class::MOP::Method::Constructor->meta->add_attribute(
534 Class::MOP::Attribute->new('associated_metaclass' => (
535 init_arg => "metaclass", # FIXME alias and rename
537 'associated_metaclass' => \&Class::MOP::Method::Constructor::associated_metaclass
542 ## --------------------------------------------------------
543 ## Class::MOP::Instance
546 # these don't yet do much of anything, but are just
547 # included for completeness
549 Class::MOP::Instance->meta->add_attribute(
550 Class::MOP::Attribute->new('associated_metaclass',
551 reader => { associated_metaclass => \&Class::MOP::Instance::associated_metaclass },
555 Class::MOP::Instance->meta->add_attribute(
556 Class::MOP::Attribute->new('_class_name',
558 reader => { _class_name => \&Class::MOP::Instance::_class_name },
559 #lazy => 1, # not yet supported by Class::MOP but out our version does it anyway
560 #default => sub { $_[0]->associated_metaclass->name },
564 Class::MOP::Instance->meta->add_attribute(
565 Class::MOP::Attribute->new('attributes',
566 reader => { attributes => \&Class::MOP::Instance::attributes },
570 Class::MOP::Instance->meta->add_attribute(
571 Class::MOP::Attribute->new('slots',
572 reader => { slots => \&Class::MOP::Instance::slots },
576 Class::MOP::Instance->meta->add_attribute(
577 Class::MOP::Attribute->new('slot_hash',
578 reader => { slot_hash => \&Class::MOP::Instance::slot_hash },
583 # we need the meta instance of the meta instance to be created now, in order
584 # for the constructor to be able to use it
585 Class::MOP::Instance->meta->get_meta_instance;
587 # pretend the add_method never happenned. it hasn't yet affected anything
588 undef Class::MOP::Instance->meta->{_package_cache_flag};
590 ## --------------------------------------------------------
591 ## Now close all the Class::MOP::* classes
594 # we don't need to inline the
595 # constructors or the accessors
596 # this only lengthens the compile
597 # time of the MOP, and gives us
598 # no actual benefits.
600 $_->meta->make_immutable(
601 inline_constructor => 1,
602 replace_constructor => 1,
603 constructor_name => "_new",
604 inline_accessors => 0,
610 Class::MOP::Attribute
616 Class::MOP::Method::Generated
618 Class::MOP::Method::Accessor
619 Class::MOP::Method::Constructor
620 Class::MOP::Method::Wrapped
631 Class::MOP - A Meta Object Protocol for Perl 5
635 This module is a fully functioning meta object protocol for the
636 Perl 5 object system. It makes no attempt to change the behavior or
637 characteristics of the Perl 5 object system, only to create a
638 protocol for its manipulation and introspection.
640 That said, it does attempt to create the tools for building a rich
641 set of extensions to the Perl 5 object system. Every attempt has been
642 made for these tools to keep to the spirit of the Perl 5 object
643 system that we all know and love.
645 This documentation is admittedly sparse on details, as time permits
646 I will try to improve them. For now, I suggest looking at the items
647 listed in the L<SEE ALSO> section for more information. In particular
648 the book "The Art of the Meta Object Protocol" was very influential
649 in the development of this system.
651 =head2 What is a Meta Object Protocol?
653 A meta object protocol is an API to an object system.
655 To be more specific, it is a set of abstractions of the components of
656 an object system (typically things like; classes, object, methods,
657 object attributes, etc.). These abstractions can then be used to both
658 inspect and manipulate the object system which they describe.
660 It can be said that there are two MOPs for any object system; the
661 implicit MOP, and the explicit MOP. The implicit MOP handles things
662 like method dispatch or inheritance, which happen automatically as
663 part of how the object system works. The explicit MOP typically
664 handles the introspection/reflection features of the object system.
665 All object systems have implicit MOPs, without one, they would not
666 work. Explict MOPs however as less common, and depending on the
667 language can vary from restrictive (Reflection in Java or C#) to
668 wide open (CLOS is a perfect example).
670 =head2 Yet Another Class Builder!! Why?
672 This is B<not> a class builder so much as it is a I<class builder
673 B<builder>>. My intent is that an end user does not use this module
674 directly, but instead this module is used by module authors to
675 build extensions and features onto the Perl 5 object system.
677 =head2 Who is this module for?
679 This module is specifically for anyone who has ever created or
680 wanted to create a module for the Class:: namespace. The tools which
681 this module will provide will hopefully make it easier to do more
682 complex things with Perl 5 classes by removing such barriers as
683 the need to hack the symbol tables, or understand the fine details
686 =head2 What changes do I have to make to use this module?
688 This module was designed to be as unintrusive as possible. Many of
689 its features are accessible without B<any> change to your existsing
690 code at all. It is meant to be a compliment to your existing code and
691 not an intrusion on your code base. Unlike many other B<Class::>
692 modules, this module B<does not> require you subclass it, or even that
693 you C<use> it in within your module's package.
695 The only features which requires additions to your code are the
696 attribute handling and instance construction features, and these are
697 both completely optional features. The only reason for this is because
698 Perl 5's object system does not actually have these features built
699 in. More information about this feature can be found below.
701 =head2 A Note about Performance?
703 It is a common misconception that explict MOPs are performance drains.
704 But this is not a universal truth at all, it is an side-effect of
705 specific implementations. For instance, using Java reflection is much
706 slower because the JVM cannot take advantage of any compiler
707 optimizations, and the JVM has to deal with much more runtime type
708 information as well. Reflection in C# is marginally better as it was
709 designed into the language and runtime (the CLR). In contrast, CLOS
710 (the Common Lisp Object System) was built to support an explicit MOP,
711 and so performance is tuned for it.
713 This library in particular does it's absolute best to avoid putting
714 B<any> drain at all upon your code's performance. In fact, by itself
715 it does nothing to affect your existing code. So you only pay for
716 what you actually use.
718 =head2 About Metaclass compatibility
720 This module makes sure that all metaclasses created are both upwards
721 and downwards compatible. The topic of metaclass compatibility is
722 highly esoteric and is something only encountered when doing deep and
723 involved metaclass hacking. There are two basic kinds of metaclass
724 incompatibility; upwards and downwards.
726 Upwards metaclass compatibility means that the metaclass of a
727 given class is either the same as (or a subclass of) all of the
730 Downward metaclass compatibility means that the metaclasses of a
731 given class's anscestors are all either the same as (or a subclass
734 Here is a diagram showing a set of two classes (C<A> and C<B>) and
735 two metaclasses (C<Meta::A> and C<Meta::B>) which have correct
736 metaclass compatibility both upwards and downwards.
738 +---------+ +---------+
739 | Meta::A |<----| Meta::B | <....... (instance of )
740 +---------+ +---------+ <------- (inherits from)
743 +---------+ +---------+
745 +---------+ +---------+
747 As I said this is a highly esoteric topic and one you will only run
748 into if you do a lot of subclassing of B<Class::MOP::Class>. If you
749 are interested in why this is an issue see the paper
750 I<Uniform and safe metaclass composition> linked to in the
751 L<SEE ALSO> section of this document.
753 =head2 Using custom metaclasses
755 Always use the metaclass pragma when using a custom metaclass, this
756 will ensure the proper initialization order and not accidentely
757 create an incorrect type of metaclass for you. This is a very rare
758 problem, and one which can only occur if you are doing deep metaclass
759 programming. So in other words, don't worry about it.
763 The protocol is divided into 4 main sub-protocols:
767 =item The Class protocol
769 This provides a means of manipulating and introspecting a Perl 5
770 class. It handles all of symbol table hacking for you, and provides
771 a rich set of methods that go beyond simple package introspection.
773 See L<Class::MOP::Class> for more details.
775 =item The Attribute protocol
777 This provides a consistent represenation for an attribute of a
778 Perl 5 class. Since there are so many ways to create and handle
779 attributes in Perl 5 OO, this attempts to provide as much of a
780 unified approach as possible, while giving the freedom and
781 flexibility to subclass for specialization.
783 See L<Class::MOP::Attribute> for more details.
785 =item The Method protocol
787 This provides a means of manipulating and introspecting methods in
788 the Perl 5 object system. As with attributes, there are many ways to
789 approach this topic, so we try to keep it pretty basic, while still
790 making it possible to extend the system in many ways.
792 See L<Class::MOP::Method> for more details.
794 =item The Instance protocol
796 This provides a layer of abstraction for creating object instances.
797 Since the other layers use this protocol, it is relatively easy to
798 change the type of your instances from the default HASH ref to other
799 types of references. Several examples are provided in the F<examples/>
800 directory included in this distribution.
802 See L<Class::MOP::Instance> for more details.
812 =item I<IS_RUNNING_ON_5_10>
814 We set this constant depending on what version perl we are on, this
815 allows us to take advantage of new 5.10 features and stay backwards
820 Whether or not C<mro> provides C<get_isarev>, a much faster way to get all the
821 subclasses of a certain class.
825 =head2 Utility functions
829 =item B<load_class ($class_name)>
831 This will load a given C<$class_name> and if it does not have an
832 already initialized metaclass, then it will intialize one for it.
833 This function can be used in place of tricks like
834 C<eval "use $module"> or using C<require>.
836 =item B<is_class_loaded ($class_name)>
838 This will return a boolean depending on if the C<$class_name> has
841 NOTE: This does a basic check of the symbol table to try and
842 determine as best it can if the C<$class_name> is loaded, it
843 is probably correct about 99% of the time.
845 =item B<check_package_cache_flag ($pkg)>
847 This will return an integer that is managed by C<Class::MOP::Class>
848 to determine if a module's symbol table has been altered.
850 In Perl 5.10 or greater, this flag is package specific. However in
851 versions prior to 5.10, this will use the C<PL_sub_generation> variable
852 which is not package specific.
854 =item B<get_code_info ($code)>
856 This function returns two values, the name of the package the C<$code>
857 is from and the name of the C<$code> itself. This is used by several
858 elements of the MOP to detemine where a given C<$code> reference is from.
860 =item B<subname ($name, $code)>
862 B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
864 If possible, we will load the L<Sub::Name> module and this will function
865 as C<Sub::Name::subname> does, otherwise it will just return the C<$code>
868 =item B<in_global_destruction>
870 If L<Devel::GlobalDestruction> is available, this returns true under global
873 Otherwise it's a constant returning false.
877 =head2 Metaclass cache functions
879 Class::MOP holds a cache of metaclasses, the following are functions
880 (B<not methods>) which can be used to access that cache. It is not
881 recommended that you mess with this, bad things could happen. But if
882 you are brave and willing to risk it, go for it.
886 =item B<get_all_metaclasses>
888 This will return an hash of all the metaclass instances that have
889 been cached by B<Class::MOP::Class> keyed by the package name.
891 =item B<get_all_metaclass_instances>
893 This will return an array of all the metaclass instances that have
894 been cached by B<Class::MOP::Class>.
896 =item B<get_all_metaclass_names>
898 This will return an array of all the metaclass names that have
899 been cached by B<Class::MOP::Class>.
901 =item B<get_metaclass_by_name ($name)>
903 This will return a cached B<Class::MOP::Class> instance of nothing
904 if no metaclass exist by that C<$name>.
906 =item B<store_metaclass_by_name ($name, $meta)>
908 This will store a metaclass in the cache at the supplied C<$key>.
910 =item B<weaken_metaclass ($name)>
912 In rare cases it is desireable to store a weakened reference in
913 the metaclass cache. This function will weaken the reference to
914 the metaclass stored in C<$name>.
916 =item B<does_metaclass_exist ($name)>
918 This will return true of there exists a metaclass stored in the
919 C<$name> key and return false otherwise.
921 =item B<remove_metaclass_by_name ($name)>
923 This will remove a the metaclass stored in the C<$name> key.
931 There are very few books out on Meta Object Protocols and Metaclasses
932 because it is such an esoteric topic. The following books are really
933 the only ones I have found. If you know of any more, B<I<please>>
934 email me and let me know, I would love to hear about them.
938 =item "The Art of the Meta Object Protocol"
940 =item "Advances in Object-Oriented Metalevel Architecture and Reflection"
942 =item "Putting MetaClasses to Work"
944 =item "Smalltalk: The Language"
952 =item Uniform and safe metaclass composition
954 An excellent paper by the people who brought us the original Traits paper.
955 This paper is on how Traits can be used to do safe metaclass composition,
956 and offers an excellent introduction section which delves into the topic of
957 metaclass compatibility.
959 L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
961 =item Safe Metaclass Programming
963 This paper seems to precede the above paper, and propose a mix-in based
964 approach as opposed to the Traits based approach. Both papers have similar
965 information on the metaclass compatibility problem space.
967 L<http://citeseer.ist.psu.edu/37617.html>
975 =item The Perl 6 MetaModel work in the Pugs project
979 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
981 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
991 =item CPAN Module Review of Class::MOP
993 L<http://www.oreillynet.com/onlamp/blog/2006/06/cpan_module_review_classmop.html>
997 =head1 SIMILAR MODULES
999 As I have said above, this module is a class-builder-builder, so it is
1000 not the same thing as modules like L<Class::Accessor> and
1001 L<Class::MethodMaker>. That being said there are very few modules on CPAN
1002 with similar goals to this module. The one I have found which is most
1003 like this module is L<Class::Meta>, although it's philosophy and the MOP it
1004 creates are very different from this modules.
1008 All complex software has bugs lurking in it, and this module is no
1009 exception. If you find a bug please either email me, or add the bug
1012 =head1 ACKNOWLEDGEMENTS
1018 Thanks to Rob for actually getting the development of this module kick-started.
1024 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1026 B<with contributions from:>
1028 Brandon (blblack) Black
1030 Guillermo (groditi) Roditi
1034 Rob (robkinyon) Kinyon
1036 Yuval (nothingmuch) Kogman
1038 Scott (konobi) McWhirter
1040 =head1 COPYRIGHT AND LICENSE
1042 Copyright 2006-2008 by Infinity Interactive, Inc.
1044 L<http://www.iinteractive.com>
1046 This library is free software; you can redistribute it and/or modify
1047 it under the same terms as Perl itself.