10 use Scalar::Util 'weaken';
12 use Class::MOP::Class;
13 use Class::MOP::Attribute;
14 use Class::MOP::Method;
16 use Class::MOP::Immutable;
20 our $VERSION = '0.61';
21 our $AUTHORITY = 'cpan:STEVAN';
23 *IS_RUNNING_ON_5_10 = ($] < 5.009_005)
28 # we may not use this yet, but once
29 # the get_code_info XS gets merged
30 # upstream to it, we will always use
31 # it. But for now it is just kinda
34 require Sub::Identify;
36 # stash these for a sec, and see how things go
37 my $_PP_subname = sub { $_[1] };
38 my $_PP_get_code_info = \&Sub::Identify::get_code_info;
40 if ($ENV{CLASS_MOP_NO_XS}) {
42 # this is if you really want things
43 # to be slow, then you can force the
44 # no-XS rule this way, otherwise we
45 # make an effort to load as much of
48 no warnings 'prototype', 'redefine';
50 unless (IS_RUNNING_ON_5_10()) {
51 # get this from MRO::Compat ...
52 *check_package_cache_flag = \&MRO::Compat::__get_pkg_gen_pp;
56 # but if we are running 5.10
57 # there is no need to use the
58 # Pure Perl version since we
59 # can use the built in mro
62 *check_package_cache_flag = \&mro::get_pkg_gen;
64 # our own version of Sub::Name
65 *subname = $_PP_subname;
66 # and the Sub::Identify version of the get_code_info
67 *get_code_info = $_PP_get_code_info;
70 # now try our best to get as much
71 # of the XS loaded as possible
76 XSLoader::load( 'Class::MOP', $VERSION );
78 die $@ if $@ && $@ !~ /object version|loadable object/;
80 # okay, so the XS failed to load, so
81 # use the pure perl one instead.
82 *get_code_info = $_PP_get_code_info if $@;
85 # get it from MRO::Compat
86 *check_package_cache_flag = \&mro::get_pkg_gen;
88 # now try and load the Sub::Name
89 # module and use that as a means
90 # for naming our CVs, if not, we
91 # use the workaround instead.
92 if ( eval { require Sub::Name } ) {
93 *subname = \&Sub::Name::subname;
96 *subname = $_PP_subname;
102 # Metaclasses are singletons, so we cache them here.
103 # there is no need to worry about destruction though
104 # because they should die only when the program dies.
105 # After all, do package definitions even get reaped?
108 # means of accessing all the metaclasses that have
109 # been initialized thus far (for mugwumps obj browser)
110 sub get_all_metaclasses { %METAS }
111 sub get_all_metaclass_instances { values %METAS }
112 sub get_all_metaclass_names { keys %METAS }
113 sub get_metaclass_by_name { $METAS{$_[0]} }
114 sub store_metaclass_by_name { $METAS{$_[0]} = $_[1] }
115 sub weaken_metaclass { weaken($METAS{$_[0]}) }
116 sub does_metaclass_exist { exists $METAS{$_[0]} && defined $METAS{$_[0]} }
117 sub remove_metaclass_by_name { $METAS{$_[0]} = undef }
120 # We only cache metaclasses, meaning instances of
121 # Class::MOP::Class. We do not cache instance of
122 # Class::MOP::Package or Class::MOP::Module. Mostly
123 # because I don't yet see a good reason to do so.
129 if (ref($class) || !defined($class) || !length($class)) {
130 my $display = defined($class) ? $class : 'undef';
131 confess "Invalid class name ($display)";
134 # see if this is already
135 # loaded in the symbol table
136 return 1 if is_class_loaded($class);
137 # otherwise require it ...
138 my $file = $class . '.pm';
140 eval { CORE::require($file) };
141 confess "Could not load class ($class) because : $@" if $@;
142 unless (does_metaclass_exist($class)) {
143 eval { Class::MOP::Class->initialize($class) };
144 confess "Could not initialize class ($class) because : $@" if $@;
146 1; # return true if it worked
149 sub is_class_loaded {
152 return 0 if ref($class) || !defined($class) || !length($class);
154 # walk the symbol table tree to avoid autovififying
155 # \*{${main::}{"Foo::"}} == \*main::Foo::
158 foreach my $part (split('::', $class)) {
159 return 0 unless exists ${$$pack}{"${part}::"};
160 $pack = \*{${$$pack}{"${part}::"}};
163 # check for $VERSION or @ISA
164 return 1 if exists ${$$pack}{VERSION}
165 && defined *{${$$pack}{VERSION}}{SCALAR};
166 return 1 if exists ${$$pack}{ISA}
167 && defined *{${$$pack}{ISA}}{ARRAY};
169 # check for any method
170 foreach ( keys %{$$pack} ) {
171 next if substr($_, -2, 2) eq '::';
173 my $glob = ${$$pack}{$_} || next;
175 if ( IS_RUNNING_ON_5_10 ) {
176 return 1 if ref $glob eq 'SCALAR';
179 return 1 if defined *{$glob}{CODE};
187 ## ----------------------------------------------------------------------------
188 ## Setting up our environment ...
189 ## ----------------------------------------------------------------------------
190 ## Class::MOP needs to have a few things in the global perl environment so
191 ## that it can operate effectively. Those things are done here.
192 ## ----------------------------------------------------------------------------
194 # ... nothing yet actually ;)
196 ## ----------------------------------------------------------------------------
198 ## ----------------------------------------------------------------------------
199 ## The code below here is to bootstrap our MOP with itself. This is also
200 ## sometimes called "tying the knot". By doing this, we make it much easier
201 ## to extend the MOP through subclassing and such since now you can use the
202 ## MOP itself to extend itself.
204 ## Yes, I know, thats weird and insane, but it's a good thing, trust me :)
205 ## ----------------------------------------------------------------------------
207 # We need to add in the meta-attributes here so that
208 # any subclass of Class::MOP::* will be able to
209 # inherit them using &construct_instance
211 ## --------------------------------------------------------
212 ## Class::MOP::Package
214 Class::MOP::Package->meta->add_attribute(
215 Class::MOP::Attribute->new('$!package' => (
217 # NOTE: we need to do this in order
218 # for the instance meta-object to
219 # not fall into meta-circular death
221 # we just alias the original method
222 # rather than re-produce it here
223 'name' => \&Class::MOP::Package::name
225 init_arg => 'package',
229 Class::MOP::Package->meta->add_attribute(
230 Class::MOP::Attribute->new('%!namespace' => (
233 # we just alias the original method
234 # rather than re-produce it here
235 'namespace' => \&Class::MOP::Package::namespace
238 default => sub { \undef }
243 # use the metaclass to construct the meta-package
244 # which is a superclass of the metaclass itself :P
245 Class::MOP::Package->meta->add_method('initialize' => sub {
247 my $package_name = shift;
248 $class->meta->new_object('package' => $package_name, @_);
251 ## --------------------------------------------------------
252 ## Class::MOP::Module
255 # yeah this is kind of stretching things a bit,
256 # but truthfully the version should be an attribute
257 # of the Module, the weirdness comes from having to
258 # stick to Perl 5 convention and store it in the
259 # $VERSION package variable. Basically if you just
260 # squint at it, it will look how you want it to look.
261 # Either as a package variable, or as a attribute of
262 # the metaclass, isn't abstraction great :)
264 Class::MOP::Module->meta->add_attribute(
265 Class::MOP::Attribute->new('$!version' => (
268 # we just alias the original method
269 # rather than re-produce it here
270 'version' => \&Class::MOP::Module::version
273 default => sub { \undef }
278 # By following the same conventions as version here,
279 # we are opening up the possibility that people can
280 # use the $AUTHORITY in non-Class::MOP modules as
283 Class::MOP::Module->meta->add_attribute(
284 Class::MOP::Attribute->new('$!authority' => (
287 # we just alias the original method
288 # rather than re-produce it here
289 'authority' => \&Class::MOP::Module::authority
292 default => sub { \undef }
296 ## --------------------------------------------------------
299 Class::MOP::Class->meta->add_attribute(
300 Class::MOP::Attribute->new('%!attributes' => (
302 # NOTE: we need to do this in order
303 # for the instance meta-object to
304 # not fall into meta-circular death
306 # we just alias the original method
307 # rather than re-produce it here
308 'get_attribute_map' => \&Class::MOP::Class::get_attribute_map
310 init_arg => 'attributes',
311 default => sub { {} }
315 Class::MOP::Class->meta->add_attribute(
316 Class::MOP::Attribute->new('%!methods' => (
317 init_arg => 'methods',
320 # we just alias the original method
321 # rather than re-produce it here
322 'get_method_map' => \&Class::MOP::Class::get_method_map
324 default => sub { {} }
328 Class::MOP::Class->meta->add_attribute(
329 Class::MOP::Attribute->new('@!superclasses' => (
332 # we just alias the original method
333 # rather than re-produce it here
334 'superclasses' => \&Class::MOP::Class::superclasses
337 default => sub { \undef }
341 Class::MOP::Class->meta->add_attribute(
342 Class::MOP::Attribute->new('$!attribute_metaclass' => (
345 # we just alias the original method
346 # rather than re-produce it here
347 'attribute_metaclass' => \&Class::MOP::Class::attribute_metaclass
349 init_arg => 'attribute_metaclass',
350 default => 'Class::MOP::Attribute',
354 Class::MOP::Class->meta->add_attribute(
355 Class::MOP::Attribute->new('$!method_metaclass' => (
358 # we just alias the original method
359 # rather than re-produce it here
360 'method_metaclass' => \&Class::MOP::Class::method_metaclass
362 init_arg => 'method_metaclass',
363 default => 'Class::MOP::Method',
367 Class::MOP::Class->meta->add_attribute(
368 Class::MOP::Attribute->new('$!instance_metaclass' => (
370 # NOTE: we need to do this in order
371 # for the instance meta-object to
372 # not fall into meta-circular death
374 # we just alias the original method
375 # rather than re-produce it here
376 'instance_metaclass' => \&Class::MOP::Class::instance_metaclass
378 init_arg => 'instance_metaclass',
379 default => 'Class::MOP::Instance',
384 # we don't actually need to tie the knot with
385 # Class::MOP::Class here, it is actually handled
386 # within Class::MOP::Class itself in the
387 # construct_class_instance method.
389 ## --------------------------------------------------------
390 ## Class::MOP::Attribute
392 Class::MOP::Attribute->meta->add_attribute(
393 Class::MOP::Attribute->new('$!name' => (
396 # NOTE: we need to do this in order
397 # for the instance meta-object to
398 # not fall into meta-circular death
400 # we just alias the original method
401 # rather than re-produce it here
402 'name' => \&Class::MOP::Attribute::name
407 Class::MOP::Attribute->meta->add_attribute(
408 Class::MOP::Attribute->new('$!associated_class' => (
409 init_arg => 'associated_class',
411 # NOTE: we need to do this in order
412 # for the instance meta-object to
413 # not fall into meta-circular death
415 # we just alias the original method
416 # rather than re-produce it here
417 'associated_class' => \&Class::MOP::Attribute::associated_class
422 Class::MOP::Attribute->meta->add_attribute(
423 Class::MOP::Attribute->new('$!accessor' => (
424 init_arg => 'accessor',
425 reader => { 'accessor' => \&Class::MOP::Attribute::accessor },
426 predicate => { 'has_accessor' => \&Class::MOP::Attribute::has_accessor },
430 Class::MOP::Attribute->meta->add_attribute(
431 Class::MOP::Attribute->new('$!reader' => (
432 init_arg => 'reader',
433 reader => { 'reader' => \&Class::MOP::Attribute::reader },
434 predicate => { 'has_reader' => \&Class::MOP::Attribute::has_reader },
438 Class::MOP::Attribute->meta->add_attribute(
439 Class::MOP::Attribute->new('$!initializer' => (
440 init_arg => 'initializer',
441 reader => { 'initializer' => \&Class::MOP::Attribute::initializer },
442 predicate => { 'has_initializer' => \&Class::MOP::Attribute::has_initializer },
446 Class::MOP::Attribute->meta->add_attribute(
447 Class::MOP::Attribute->new('$!writer' => (
448 init_arg => 'writer',
449 reader => { 'writer' => \&Class::MOP::Attribute::writer },
450 predicate => { 'has_writer' => \&Class::MOP::Attribute::has_writer },
454 Class::MOP::Attribute->meta->add_attribute(
455 Class::MOP::Attribute->new('$!predicate' => (
456 init_arg => 'predicate',
457 reader => { 'predicate' => \&Class::MOP::Attribute::predicate },
458 predicate => { 'has_predicate' => \&Class::MOP::Attribute::has_predicate },
462 Class::MOP::Attribute->meta->add_attribute(
463 Class::MOP::Attribute->new('$!clearer' => (
464 init_arg => 'clearer',
465 reader => { 'clearer' => \&Class::MOP::Attribute::clearer },
466 predicate => { 'has_clearer' => \&Class::MOP::Attribute::has_clearer },
470 Class::MOP::Attribute->meta->add_attribute(
471 Class::MOP::Attribute->new('$!builder' => (
472 init_arg => 'builder',
473 reader => { 'builder' => \&Class::MOP::Attribute::builder },
474 predicate => { 'has_builder' => \&Class::MOP::Attribute::has_builder },
478 Class::MOP::Attribute->meta->add_attribute(
479 Class::MOP::Attribute->new('$!init_arg' => (
480 init_arg => 'init_arg',
481 reader => { 'init_arg' => \&Class::MOP::Attribute::init_arg },
482 predicate => { 'has_init_arg' => \&Class::MOP::Attribute::has_init_arg },
486 Class::MOP::Attribute->meta->add_attribute(
487 Class::MOP::Attribute->new('$!default' => (
488 init_arg => 'default',
489 # default has a custom 'reader' method ...
490 predicate => { 'has_default' => \&Class::MOP::Attribute::has_default },
494 Class::MOP::Attribute->meta->add_attribute(
495 Class::MOP::Attribute->new('@!associated_methods' => (
496 init_arg => 'associated_methods',
497 reader => { 'associated_methods' => \&Class::MOP::Attribute::associated_methods },
498 default => sub { [] }
502 # NOTE: (meta-circularity)
503 # This should be one of the last things done
504 # it will "tie the knot" with Class::MOP::Attribute
505 # so that it uses the attributes meta-objects
506 # to construct itself.
507 Class::MOP::Attribute->meta->add_method('new' => sub {
512 (defined $name && $name)
513 || confess "You must provide a name for the attribute";
514 $options{init_arg} = $name
515 if not exists $options{init_arg};
517 if(exists $options{builder}){
518 confess("builder must be a defined scalar value which is a method name")
519 if ref $options{builder} || !(defined $options{builder});
520 confess("Setting both default and builder is not allowed.")
521 if exists $options{default};
523 (Class::MOP::Attribute::is_default_a_coderef(\%options))
524 || confess("References are not allowed as default values, you must ".
525 "wrap the default of '$name' in a CODE reference (ex: sub { [] } and not [])")
526 if exists $options{default} && ref $options{default};
528 # return the new object
529 $class->meta->new_object(name => $name, %options);
532 Class::MOP::Attribute->meta->add_method('clone' => sub {
534 $self->meta->clone_object($self, @_);
537 ## --------------------------------------------------------
538 ## Class::MOP::Method
540 Class::MOP::Method->meta->add_attribute(
541 Class::MOP::Attribute->new('&!body' => (
543 reader => { 'body' => \&Class::MOP::Method::body },
547 Class::MOP::Method->meta->add_attribute(
548 Class::MOP::Attribute->new('$!package_name' => (
549 init_arg => 'package_name',
550 reader => { 'package_name' => \&Class::MOP::Method::package_name },
554 Class::MOP::Method->meta->add_attribute(
555 Class::MOP::Attribute->new('$!name' => (
557 reader => { 'name' => \&Class::MOP::Method::name },
561 Class::MOP::Method->meta->add_method('wrap' => sub {
566 ('CODE' eq ref($code))
567 || confess "You must supply a CODE reference to bless, not (" . ($code || 'undef') . ")";
569 ($options{package_name} && $options{name})
570 || confess "You must supply the package_name and name parameters";
572 # return the new object
573 $class->meta->new_object(body => $code, %options);
576 Class::MOP::Method->meta->add_method('clone' => sub {
578 $self->meta->clone_object($self, @_);
581 ## --------------------------------------------------------
582 ## Class::MOP::Method::Wrapped
585 # the way this item is initialized, this
586 # really does not follow the standard
587 # practices of attributes, but we put
588 # it here for completeness
589 Class::MOP::Method::Wrapped->meta->add_attribute(
590 Class::MOP::Attribute->new('%!modifier_table')
593 ## --------------------------------------------------------
594 ## Class::MOP::Method::Generated
596 Class::MOP::Method::Generated->meta->add_attribute(
597 Class::MOP::Attribute->new('$!is_inline' => (
598 init_arg => 'is_inline',
599 reader => { 'is_inline' => \&Class::MOP::Method::Generated::is_inline },
604 Class::MOP::Method::Generated->meta->add_method('new' => sub {
605 my ($class, %options) = @_;
606 ($options{package_name} && $options{name})
607 || confess "You must supply the package_name and name parameters";
608 my $self = $class->meta->new_object(%options);
609 $self->initialize_body;
613 ## --------------------------------------------------------
614 ## Class::MOP::Method::Accessor
616 Class::MOP::Method::Accessor->meta->add_attribute(
617 Class::MOP::Attribute->new('$!attribute' => (
618 init_arg => 'attribute',
620 'associated_attribute' => \&Class::MOP::Method::Accessor::associated_attribute
625 Class::MOP::Method::Accessor->meta->add_attribute(
626 Class::MOP::Attribute->new('$!accessor_type' => (
627 init_arg => 'accessor_type',
628 reader => { 'accessor_type' => \&Class::MOP::Method::Accessor::accessor_type },
632 Class::MOP::Method::Accessor->meta->add_method('new' => sub {
636 (exists $options{attribute})
637 || confess "You must supply an attribute to construct with";
639 (exists $options{accessor_type})
640 || confess "You must supply an accessor_type to construct with";
642 (Scalar::Util::blessed($options{attribute}) && $options{attribute}->isa('Class::MOP::Attribute'))
643 || confess "You must supply an attribute which is a 'Class::MOP::Attribute' instance";
645 ($options{package_name} && $options{name})
646 || confess "You must supply the package_name and name parameters";
648 # return the new object
649 my $self = $class->meta->new_object(%options);
651 # we don't want this creating
652 # a cycle in the code, if not
654 Scalar::Util::weaken($self->{'$!attribute'});
656 $self->initialize_body;
662 ## --------------------------------------------------------
663 ## Class::MOP::Method::Constructor
665 Class::MOP::Method::Constructor->meta->add_attribute(
666 Class::MOP::Attribute->new('%!options' => (
667 init_arg => 'options',
669 'options' => \&Class::MOP::Method::Constructor::options
671 default => sub { +{} }
675 Class::MOP::Method::Constructor->meta->add_attribute(
676 Class::MOP::Attribute->new('$!associated_metaclass' => (
677 init_arg => 'metaclass',
679 'associated_metaclass' => \&Class::MOP::Method::Constructor::associated_metaclass
684 Class::MOP::Method::Constructor->meta->add_method('new' => sub {
688 (Scalar::Util::blessed $options{metaclass} && $options{metaclass}->isa('Class::MOP::Class'))
689 || confess "You must pass a metaclass instance if you want to inline"
690 if $options{is_inline};
692 ($options{package_name} && $options{name})
693 || confess "You must supply the package_name and name parameters";
695 # return the new object
696 my $self = $class->meta->new_object(%options);
698 # we don't want this creating
699 # a cycle in the code, if not
701 Scalar::Util::weaken($self->{'$!associated_metaclass'});
703 $self->initialize_body;
708 ## --------------------------------------------------------
709 ## Class::MOP::Instance
712 # these don't yet do much of anything, but are just
713 # included for completeness
715 Class::MOP::Instance->meta->add_attribute(
716 Class::MOP::Attribute->new('$!meta')
719 Class::MOP::Instance->meta->add_attribute(
720 Class::MOP::Attribute->new('@!slots')
723 ## --------------------------------------------------------
724 ## Now close all the Class::MOP::* classes
727 # we don't need to inline the
728 # constructors or the accessors
729 # this only lengthens the compile
730 # time of the MOP, and gives us
731 # no actual benefits.
733 $_->meta->make_immutable(
734 inline_constructor => 0,
735 inline_accessors => 0,
741 Class::MOP::Attribute
747 Class::MOP::Method::Generated
749 Class::MOP::Method::Accessor
750 Class::MOP::Method::Constructor
751 Class::MOP::Method::Wrapped
762 Class::MOP - A Meta Object Protocol for Perl 5
766 This module is a fully functioning meta object protocol for the
767 Perl 5 object system. It makes no attempt to change the behavior or
768 characteristics of the Perl 5 object system, only to create a
769 protocol for its manipulation and introspection.
771 That said, it does attempt to create the tools for building a rich
772 set of extensions to the Perl 5 object system. Every attempt has been
773 made for these tools to keep to the spirit of the Perl 5 object
774 system that we all know and love.
776 This documentation is admittedly sparse on details, as time permits
777 I will try to improve them. For now, I suggest looking at the items
778 listed in the L<SEE ALSO> section for more information. In particular
779 the book "The Art of the Meta Object Protocol" was very influential
780 in the development of this system.
782 =head2 What is a Meta Object Protocol?
784 A meta object protocol is an API to an object system.
786 To be more specific, it is a set of abstractions of the components of
787 an object system (typically things like; classes, object, methods,
788 object attributes, etc.). These abstractions can then be used to both
789 inspect and manipulate the object system which they describe.
791 It can be said that there are two MOPs for any object system; the
792 implicit MOP, and the explicit MOP. The implicit MOP handles things
793 like method dispatch or inheritance, which happen automatically as
794 part of how the object system works. The explicit MOP typically
795 handles the introspection/reflection features of the object system.
796 All object systems have implicit MOPs, without one, they would not
797 work. Explict MOPs however as less common, and depending on the
798 language can vary from restrictive (Reflection in Java or C#) to
799 wide open (CLOS is a perfect example).
801 =head2 Yet Another Class Builder!! Why?
803 This is B<not> a class builder so much as it is a I<class builder
804 B<builder>>. My intent is that an end user does not use this module
805 directly, but instead this module is used by module authors to
806 build extensions and features onto the Perl 5 object system.
808 =head2 Who is this module for?
810 This module is specifically for anyone who has ever created or
811 wanted to create a module for the Class:: namespace. The tools which
812 this module will provide will hopefully make it easier to do more
813 complex things with Perl 5 classes by removing such barriers as
814 the need to hack the symbol tables, or understand the fine details
817 =head2 What changes do I have to make to use this module?
819 This module was designed to be as unintrusive as possible. Many of
820 its features are accessible without B<any> change to your existsing
821 code at all. It is meant to be a compliment to your existing code and
822 not an intrusion on your code base. Unlike many other B<Class::>
823 modules, this module B<does not> require you subclass it, or even that
824 you C<use> it in within your module's package.
826 The only features which requires additions to your code are the
827 attribute handling and instance construction features, and these are
828 both completely optional features. The only reason for this is because
829 Perl 5's object system does not actually have these features built
830 in. More information about this feature can be found below.
832 =head2 A Note about Performance?
834 It is a common misconception that explict MOPs are performance drains.
835 But this is not a universal truth at all, it is an side-effect of
836 specific implementations. For instance, using Java reflection is much
837 slower because the JVM cannot take advantage of any compiler
838 optimizations, and the JVM has to deal with much more runtime type
839 information as well. Reflection in C# is marginally better as it was
840 designed into the language and runtime (the CLR). In contrast, CLOS
841 (the Common Lisp Object System) was built to support an explicit MOP,
842 and so performance is tuned for it.
844 This library in particular does it's absolute best to avoid putting
845 B<any> drain at all upon your code's performance. In fact, by itself
846 it does nothing to affect your existing code. So you only pay for
847 what you actually use.
849 =head2 About Metaclass compatibility
851 This module makes sure that all metaclasses created are both upwards
852 and downwards compatible. The topic of metaclass compatibility is
853 highly esoteric and is something only encountered when doing deep and
854 involved metaclass hacking. There are two basic kinds of metaclass
855 incompatibility; upwards and downwards.
857 Upwards metaclass compatibility means that the metaclass of a
858 given class is either the same as (or a subclass of) all of the
861 Downward metaclass compatibility means that the metaclasses of a
862 given class's anscestors are all either the same as (or a subclass
865 Here is a diagram showing a set of two classes (C<A> and C<B>) and
866 two metaclasses (C<Meta::A> and C<Meta::B>) which have correct
867 metaclass compatibility both upwards and downwards.
869 +---------+ +---------+
870 | Meta::A |<----| Meta::B | <....... (instance of )
871 +---------+ +---------+ <------- (inherits from)
874 +---------+ +---------+
876 +---------+ +---------+
878 As I said this is a highly esoteric topic and one you will only run
879 into if you do a lot of subclassing of B<Class::MOP::Class>. If you
880 are interested in why this is an issue see the paper
881 I<Uniform and safe metaclass composition> linked to in the
882 L<SEE ALSO> section of this document.
884 =head2 Using custom metaclasses
886 Always use the metaclass pragma when using a custom metaclass, this
887 will ensure the proper initialization order and not accidentely
888 create an incorrect type of metaclass for you. This is a very rare
889 problem, and one which can only occur if you are doing deep metaclass
890 programming. So in other words, don't worry about it.
894 The protocol is divided into 4 main sub-protocols:
898 =item The Class protocol
900 This provides a means of manipulating and introspecting a Perl 5
901 class. It handles all of symbol table hacking for you, and provides
902 a rich set of methods that go beyond simple package introspection.
904 See L<Class::MOP::Class> for more details.
906 =item The Attribute protocol
908 This provides a consistent represenation for an attribute of a
909 Perl 5 class. Since there are so many ways to create and handle
910 attributes in Perl 5 OO, this attempts to provide as much of a
911 unified approach as possible, while giving the freedom and
912 flexibility to subclass for specialization.
914 See L<Class::MOP::Attribute> for more details.
916 =item The Method protocol
918 This provides a means of manipulating and introspecting methods in
919 the Perl 5 object system. As with attributes, there are many ways to
920 approach this topic, so we try to keep it pretty basic, while still
921 making it possible to extend the system in many ways.
923 See L<Class::MOP::Method> for more details.
925 =item The Instance protocol
927 This provides a layer of abstraction for creating object instances.
928 Since the other layers use this protocol, it is relatively easy to
929 change the type of your instances from the default HASH ref to other
930 types of references. Several examples are provided in the F<examples/>
931 directory included in this distribution.
933 See L<Class::MOP::Instance> for more details.
943 =item I<IS_RUNNING_ON_5_10>
945 We set this constant depending on what version perl we are on, this
946 allows us to take advantage of new 5.10 features and stay backwards
951 =head2 Utility functions
955 =item B<load_class ($class_name)>
957 This will load a given C<$class_name> and if it does not have an
958 already initialized metaclass, then it will intialize one for it.
959 This function can be used in place of tricks like
960 C<eval "use $module"> or using C<require>.
962 =item B<is_class_loaded ($class_name)>
964 This will return a boolean depending on if the C<$class_name> has
967 NOTE: This does a basic check of the symbol table to try and
968 determine as best it can if the C<$class_name> is loaded, it
969 is probably correct about 99% of the time.
971 =item B<check_package_cache_flag ($pkg)>
973 This will return an integer that is managed by C<Class::MOP::Class>
974 to determine if a module's symbol table has been altered.
976 In Perl 5.10 or greater, this flag is package specific. However in
977 versions prior to 5.10, this will use the C<PL_sub_generation> variable
978 which is not package specific.
980 =item B<get_code_info ($code)>
982 This function returns two values, the name of the package the C<$code>
983 is from and the name of the C<$code> itself. This is used by several
984 elements of the MOP to detemine where a given C<$code> reference is from.
986 =item B<subname ($name, $code)>
988 B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
990 If possible, we will load the L<Sub::Name> module and this will function
991 as C<Sub::Name::subname> does, otherwise it will just return the C<$code>
996 =head2 Metaclass cache functions
998 Class::MOP holds a cache of metaclasses, the following are functions
999 (B<not methods>) which can be used to access that cache. It is not
1000 recommended that you mess with this, bad things could happen. But if
1001 you are brave and willing to risk it, go for it.
1005 =item B<get_all_metaclasses>
1007 This will return an hash of all the metaclass instances that have
1008 been cached by B<Class::MOP::Class> keyed by the package name.
1010 =item B<get_all_metaclass_instances>
1012 This will return an array of all the metaclass instances that have
1013 been cached by B<Class::MOP::Class>.
1015 =item B<get_all_metaclass_names>
1017 This will return an array of all the metaclass names that have
1018 been cached by B<Class::MOP::Class>.
1020 =item B<get_metaclass_by_name ($name)>
1022 This will return a cached B<Class::MOP::Class> instance of nothing
1023 if no metaclass exist by that C<$name>.
1025 =item B<store_metaclass_by_name ($name, $meta)>
1027 This will store a metaclass in the cache at the supplied C<$key>.
1029 =item B<weaken_metaclass ($name)>
1031 In rare cases it is desireable to store a weakened reference in
1032 the metaclass cache. This function will weaken the reference to
1033 the metaclass stored in C<$name>.
1035 =item B<does_metaclass_exist ($name)>
1037 This will return true of there exists a metaclass stored in the
1038 C<$name> key and return false otherwise.
1040 =item B<remove_metaclass_by_name ($name)>
1042 This will remove a the metaclass stored in the C<$name> key.
1050 There are very few books out on Meta Object Protocols and Metaclasses
1051 because it is such an esoteric topic. The following books are really
1052 the only ones I have found. If you know of any more, B<I<please>>
1053 email me and let me know, I would love to hear about them.
1057 =item "The Art of the Meta Object Protocol"
1059 =item "Advances in Object-Oriented Metalevel Architecture and Reflection"
1061 =item "Putting MetaClasses to Work"
1063 =item "Smalltalk: The Language"
1071 =item Uniform and safe metaclass composition
1073 An excellent paper by the people who brought us the original Traits paper.
1074 This paper is on how Traits can be used to do safe metaclass composition,
1075 and offers an excellent introduction section which delves into the topic of
1076 metaclass compatibility.
1078 L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
1080 =item Safe Metaclass Programming
1082 This paper seems to precede the above paper, and propose a mix-in based
1083 approach as opposed to the Traits based approach. Both papers have similar
1084 information on the metaclass compatibility problem space.
1086 L<http://citeseer.ist.psu.edu/37617.html>
1094 =item The Perl 6 MetaModel work in the Pugs project
1098 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
1100 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
1110 =item CPAN Module Review of Class::MOP
1112 L<http://www.oreillynet.com/onlamp/blog/2006/06/cpan_module_review_classmop.html>
1116 =head1 SIMILAR MODULES
1118 As I have said above, this module is a class-builder-builder, so it is
1119 not the same thing as modules like L<Class::Accessor> and
1120 L<Class::MethodMaker>. That being said there are very few modules on CPAN
1121 with similar goals to this module. The one I have found which is most
1122 like this module is L<Class::Meta>, although it's philosophy and the MOP it
1123 creates are very different from this modules.
1127 All complex software has bugs lurking in it, and this module is no
1128 exception. If you find a bug please either email me, or add the bug
1131 =head1 ACKNOWLEDGEMENTS
1137 Thanks to Rob for actually getting the development of this module kick-started.
1143 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1145 B<with contributions from:>
1147 Brandon (blblack) Black
1149 Guillermo (groditi) Roditi
1153 Rob (robkinyon) Kinyon
1155 Yuval (nothingmuch) Kogman
1157 Scott (konobi) McWhirter
1159 =head1 COPYRIGHT AND LICENSE
1161 Copyright 2006-2008 by Infinity Interactive, Inc.
1163 L<http://www.iinteractive.com>
1165 This library is free software; you can redistribute it and/or modify
1166 it under the same terms as Perl itself.