Implement the "eval $VERSION" trick from perlmodstyle so CPAN doesn't
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
1
2 package Class::MOP;
3
4 use strict;
5 use warnings;
6
7 use MRO::Compat;
8
9 use Carp          'confess';
10 use Scalar::Util  'weaken';
11
12 use Sub::Identify 'get_code_info';
13
14 BEGIN {
15     local $@;
16     eval {
17         require Sub::Name;
18         Sub::Name->import(qw(subname));
19         1
20     } or eval 'sub subname { $_[1] }';
21
22     # this is either part of core or set up appropriately by MRO::Compat
23     *check_package_cache_flag = \&mro::get_pkg_gen;
24
25     eval {
26         require Devel::GlobalDestruction;
27         Devel::GlobalDestruction->import("in_global_destruction");
28         1;
29     } or *in_global_destruction = sub () { '' };
30 }
31
32
33 use Class::MOP::Class;
34 use Class::MOP::Attribute;
35 use Class::MOP::Method;
36
37 use Class::MOP::Immutable;
38
39 BEGIN {
40     *IS_RUNNING_ON_5_10 = ($] < 5.009_005) 
41         ? sub () { 0 }
42         : sub () { 1 };    
43
44     *HAVE_ISAREV = defined(&mro::get_isarev)
45         ? sub () { 1 }
46         : sub () { 1 };
47 }
48
49 our $VERSION   = '0.64_01';
50 $VERSION = eval $VERSION;
51 our $AUTHORITY = 'cpan:STEVAN';    
52     
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}) {
56     my $e = do {
57         local $@;
58         eval {
59             require XSLoader;
60             __PACKAGE__->XSLoader::load($VERSION);
61         };
62         $@;
63     };
64
65     die $e if $e && $e !~ /object version|loadable object/;
66 }
67
68 {
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?
73     my %METAS;
74
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 }
85
86     # NOTE:
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.
91 }
92
93 sub load_class {
94     my $class = shift;
95
96     if (ref($class) || !defined($class) || !length($class)) {
97         my $display = defined($class) ? $class : 'undef';
98         confess "Invalid class name ($display)";
99     }
100
101     # if the class is not already loaded in the symbol table..
102     unless (is_class_loaded($class)) {
103         # require it
104         my $file = $class . '.pm';
105         $file =~ s{::}{/}g;
106         my $e = do { local $@; eval { require($file) }; $@ };
107         confess "Could not load class ($class) because : $e" if $e;
108     }
109
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;
114     }
115
116     return get_metaclass_by_name($class) if defined wantarray;
117 }
118
119 sub is_class_loaded {
120     my $class = shift;
121
122     return 0 if ref($class) || !defined($class) || !length($class);
123
124     # walk the symbol table tree to avoid autovififying
125     # \*{${main::}{"Foo::"}} == \*main::Foo::
126
127     my $pack = \*::;
128     foreach my $part (split('::', $class)) {
129         return 0 unless exists ${$$pack}{"${part}::"};
130         $pack = \*{${$$pack}{"${part}::"}};
131     }
132
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};
138
139     # check for any method
140     foreach ( keys %{$$pack} ) {
141         next if substr($_, -2, 2) eq '::';
142
143         my $glob = ${$$pack}{$_} || next;
144
145         # constant subs
146         if ( IS_RUNNING_ON_5_10 ) {
147             return 1 if ref $glob eq 'SCALAR';
148         }
149
150         return 1 if defined *{$glob}{CODE};
151     }
152
153     # fail
154     return 0;
155 }
156
157
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 ## ----------------------------------------------------------------------------
164
165 # ... nothing yet actually ;)
166
167 ## ----------------------------------------------------------------------------
168 ## Bootstrapping
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.
174 ##
175 ## Yes, I know, thats weird and insane, but it's a good thing, trust me :)
176 ## ----------------------------------------------------------------------------
177
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
181
182 ## --------------------------------------------------------
183 ## Class::MOP::Package
184
185 Class::MOP::Package->meta->add_attribute(
186     Class::MOP::Attribute->new('package' => (
187         reader   => {
188             # NOTE: we need to do this in order
189             # for the instance meta-object to
190             # not fall into meta-circular death
191             #
192             # we just alias the original method
193             # rather than re-produce it here
194             'name' => \&Class::MOP::Package::name
195         },
196     ))
197 );
198
199 Class::MOP::Package->meta->add_attribute(
200     Class::MOP::Attribute->new('namespace' => (
201         reader => {
202             # NOTE:
203             # we just alias the original method
204             # rather than re-produce it here
205             'namespace' => \&Class::MOP::Package::namespace
206         },
207         init_arg => undef,
208         default  => sub { \undef }
209     ))
210 );
211
212 ## --------------------------------------------------------
213 ## Class::MOP::Module
214
215 # NOTE:
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 :)
224
225 Class::MOP::Module->meta->add_attribute(
226     Class::MOP::Attribute->new('version' => (
227         reader => {
228             # NOTE:
229             # we just alias the original method
230             # rather than re-produce it here
231             'version' => \&Class::MOP::Module::version
232         },
233         init_arg => undef,
234         default  => sub { \undef }
235     ))
236 );
237
238 # NOTE:
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
242 # well.
243
244 Class::MOP::Module->meta->add_attribute(
245     Class::MOP::Attribute->new('authority' => (
246         reader => {
247             # NOTE:
248             # we just alias the original method
249             # rather than re-produce it here
250             'authority' => \&Class::MOP::Module::authority
251         },
252         init_arg => undef,
253         default  => sub { \undef }
254     ))
255 );
256
257 ## --------------------------------------------------------
258 ## Class::MOP::Class
259
260 Class::MOP::Class->meta->add_attribute(
261     Class::MOP::Attribute->new('attributes' => (
262         reader   => {
263             # NOTE: we need to do this in order
264             # for the instance meta-object to
265             # not fall into meta-circular death
266             #
267             # we just alias the original method
268             # rather than re-produce it here
269             'get_attribute_map' => \&Class::MOP::Class::get_attribute_map
270         },
271         default  => sub { {} }
272     ))
273 );
274
275 Class::MOP::Class->meta->add_attribute(
276     Class::MOP::Attribute->new('methods' => (
277         reader   => {
278             # NOTE:
279             # we just alias the original method
280             # rather than re-produce it here
281             'get_method_map' => \&Class::MOP::Class::get_method_map
282         },
283         default => sub { {} }
284     ))
285 );
286
287 Class::MOP::Class->meta->add_attribute(
288     Class::MOP::Attribute->new('superclasses' => (
289         accessor => {
290             # NOTE:
291             # we just alias the original method
292             # rather than re-produce it here
293             'superclasses' => \&Class::MOP::Class::superclasses
294         },
295         init_arg => undef,
296         default  => sub { \undef }
297     ))
298 );
299
300 Class::MOP::Class->meta->add_attribute(
301     Class::MOP::Attribute->new('attribute_metaclass' => (
302         reader   => {
303             # NOTE:
304             # we just alias the original method
305             # rather than re-produce it here
306             'attribute_metaclass' => \&Class::MOP::Class::attribute_metaclass
307         },
308         default  => 'Class::MOP::Attribute',
309     ))
310 );
311
312 Class::MOP::Class->meta->add_attribute(
313     Class::MOP::Attribute->new('method_metaclass' => (
314         reader   => {
315             # NOTE:
316             # we just alias the original method
317             # rather than re-produce it here
318             'method_metaclass' => \&Class::MOP::Class::method_metaclass
319         },
320         default  => 'Class::MOP::Method',
321     ))
322 );
323
324 Class::MOP::Class->meta->add_attribute(
325     Class::MOP::Attribute->new('instance_metaclass' => (
326         reader   => {
327             # NOTE: we need to do this in order
328             # for the instance meta-object to
329             # not fall into meta-circular death
330             #
331             # we just alias the original method
332             # rather than re-produce it here
333             'instance_metaclass' => \&Class::MOP::Class::instance_metaclass
334         },
335         default  => 'Class::MOP::Instance',
336     ))
337 );
338
339 # NOTE:
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.
344
345 ## --------------------------------------------------------
346 ## Class::MOP::Attribute
347
348 Class::MOP::Attribute->meta->add_attribute(
349     Class::MOP::Attribute->new('name' => (
350         reader   => {
351             # NOTE: we need to do this in order
352             # for the instance meta-object to
353             # not fall into meta-circular death
354             #
355             # we just alias the original method
356             # rather than re-produce it here
357             'name' => \&Class::MOP::Attribute::name
358         }
359     ))
360 );
361
362 Class::MOP::Attribute->meta->add_attribute(
363     Class::MOP::Attribute->new('associated_class' => (
364         reader   => {
365             # NOTE: we need to do this in order
366             # for the instance meta-object to
367             # not fall into meta-circular death
368             #
369             # we just alias the original method
370             # rather than re-produce it here
371             'associated_class' => \&Class::MOP::Attribute::associated_class
372         }
373     ))
374 );
375
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 },
380     ))
381 );
382
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 },
387     ))
388 );
389
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 },
394     ))
395 );
396
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 },
401     ))
402 );
403
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 },
408     ))
409 );
410
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 },
415     ))
416 );
417
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 },
422     ))
423 );
424
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 },
429     ))
430 );
431
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 },
436     ))
437 );
438
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 { [] }
443     ))
444 );
445
446 Class::MOP::Attribute->meta->add_method('clone' => sub {
447     my $self  = shift;
448     $self->meta->clone_object($self, @_);
449 });
450
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 },
456     ))
457 );
458
459 Class::MOP::Method->meta->add_attribute(
460     Class::MOP::Attribute->new('associated_metaclass' => (
461         reader   => { 'associated_metaclass' => \&Class::MOP::Method::associated_metaclass },
462     ))
463 );
464
465 Class::MOP::Method->meta->add_attribute(
466     Class::MOP::Attribute->new('package_name' => (
467         reader   => { 'package_name' => \&Class::MOP::Method::package_name },
468     ))
469 );
470
471 Class::MOP::Method->meta->add_attribute(
472     Class::MOP::Attribute->new('name' => (
473         reader   => { 'name' => \&Class::MOP::Method::name },
474     ))
475 );
476
477 Class::MOP::Method->meta->add_method('clone' => sub {
478     my $self  = shift;
479     $self->meta->clone_object($self, @_);
480 });
481
482 ## --------------------------------------------------------
483 ## Class::MOP::Method::Wrapped
484
485 # NOTE:
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')
492 );
493
494 ## --------------------------------------------------------
495 ## Class::MOP::Method::Generated
496
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 },
500         default  => 0, 
501     ))
502 );
503
504 ## --------------------------------------------------------
505 ## Class::MOP::Method::Accessor
506
507 Class::MOP::Method::Accessor->meta->add_attribute(
508     Class::MOP::Attribute->new('attribute' => (
509         reader   => {
510             'associated_attribute' => \&Class::MOP::Method::Accessor::associated_attribute
511         },
512     ))
513 );
514
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 },
518     ))
519 );
520
521 ## --------------------------------------------------------
522 ## Class::MOP::Method::Constructor
523
524 Class::MOP::Method::Constructor->meta->add_attribute(
525     Class::MOP::Attribute->new('options' => (
526         reader   => {
527             'options' => \&Class::MOP::Method::Constructor::options
528         },
529         default  => sub { +{} }
530     ))
531 );
532
533 Class::MOP::Method::Constructor->meta->add_attribute(
534     Class::MOP::Attribute->new('associated_metaclass' => (
535         init_arg => "metaclass", # FIXME alias and rename
536         reader   => {
537             'associated_metaclass' => \&Class::MOP::Method::Constructor::associated_metaclass
538         },
539     ))
540 );
541
542 ## --------------------------------------------------------
543 ## Class::MOP::Instance
544
545 # NOTE:
546 # these don't yet do much of anything, but are just
547 # included for completeness
548
549 Class::MOP::Instance->meta->add_attribute(
550     Class::MOP::Attribute->new('associated_metaclass',
551         reader   => { associated_metaclass => \&Class::MOP::Instance::associated_metaclass },
552     ),
553 );
554
555 Class::MOP::Instance->meta->add_attribute(
556     Class::MOP::Attribute->new('_class_name',
557         init_arg => undef,
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 },
561     ),
562 );
563
564 Class::MOP::Instance->meta->add_attribute(
565     Class::MOP::Attribute->new('attributes',
566         reader   => { attributes => \&Class::MOP::Instance::attributes },
567     ),
568 );
569
570 Class::MOP::Instance->meta->add_attribute(
571     Class::MOP::Attribute->new('slots',
572         reader   => { slots => \&Class::MOP::Instance::slots },
573     ),
574 );
575
576 Class::MOP::Instance->meta->add_attribute(
577     Class::MOP::Attribute->new('slot_hash',
578         reader   => { slot_hash => \&Class::MOP::Instance::slot_hash },
579     ),
580 );
581
582
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;
586
587 # pretend the add_method never happenned. it hasn't yet affected anything
588 undef Class::MOP::Instance->meta->{_package_cache_flag};
589
590 ## --------------------------------------------------------
591 ## Now close all the Class::MOP::* classes
592
593 # NOTE:
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.
599
600 $_->meta->make_immutable(
601     inline_constructor  => 1,
602     replace_constructor => 1,
603     constructor_name    => "_new",
604     inline_accessors => 0,
605 ) for qw/
606     Class::MOP::Package
607     Class::MOP::Module
608     Class::MOP::Class
609
610     Class::MOP::Attribute
611     Class::MOP::Method
612     Class::MOP::Instance
613
614     Class::MOP::Object
615
616     Class::MOP::Method::Generated
617
618     Class::MOP::Method::Accessor
619     Class::MOP::Method::Constructor
620     Class::MOP::Method::Wrapped
621 /;
622
623 1;
624
625 __END__
626
627 =pod
628
629 =head1 NAME
630
631 Class::MOP - A Meta Object Protocol for Perl 5
632
633 =head1 DESCRIPTON
634
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.
639
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.
644
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.
650
651 =head2 What is a Meta Object Protocol?
652
653 A meta object protocol is an API to an object system.
654
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.
659
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).
669
670 =head2 Yet Another Class Builder!! Why?
671
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.
676
677 =head2 Who is this module for?
678
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
684 of method dispatch.
685
686 =head2 What changes do I have to make to use this module?
687
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.
694
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.
700
701 =head2 A Note about Performance?
702
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.
712
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.
717
718 =head2 About Metaclass compatibility
719
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.
725
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
728 class's ancestors.
729
730 Downward metaclass compatibility means that the metaclasses of a
731 given class's anscestors are all either the same as (or a subclass
732 of) that metaclass.
733
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.
737
738     +---------+     +---------+
739     | Meta::A |<----| Meta::B |      <....... (instance of  )
740     +---------+     +---------+      <------- (inherits from)
741          ^               ^
742          :               :
743     +---------+     +---------+
744     |    A    |<----|    B    |
745     +---------+     +---------+
746
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.
752
753 =head2 Using custom metaclasses
754
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.
760
761 =head1 PROTOCOLS
762
763 The protocol is divided into 4 main sub-protocols:
764
765 =over 4
766
767 =item The Class protocol
768
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.
772
773 See L<Class::MOP::Class> for more details.
774
775 =item The Attribute protocol
776
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.
782
783 See L<Class::MOP::Attribute> for more details.
784
785 =item The Method protocol
786
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.
791
792 See L<Class::MOP::Method> for more details.
793
794 =item The Instance protocol
795
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.
801
802 See L<Class::MOP::Instance> for more details.
803
804 =back
805
806 =head1 FUNCTIONS
807
808 =head2 Constants
809
810 =over 4
811
812 =item I<IS_RUNNING_ON_5_10>
813
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 
816 compat.
817
818 =item I<HAVE_ISAREV>
819
820 Whether or not C<mro> provides C<get_isarev>, a much faster way to get all the
821 subclasses of a certain class.
822
823 =back
824
825 =head2 Utility functions
826
827 =over 4
828
829 =item B<load_class ($class_name)>
830
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>.
835
836 =item B<is_class_loaded ($class_name)>
837
838 This will return a boolean depending on if the C<$class_name> has
839 been loaded.
840
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.
844
845 =item B<check_package_cache_flag ($pkg)>
846
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. 
849
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. 
853
854 =item B<get_code_info ($code)>
855
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.
859
860 =item B<subname ($name, $code)>
861
862 B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
863
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>
866 argument.
867
868 =item B<in_global_destruction>
869
870 If L<Devel::GlobalDestruction> is available, this returns true under global
871 destruction.
872
873 Otherwise it's a constant returning false.
874
875 =back
876
877 =head2 Metaclass cache functions
878
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.
883
884 =over 4
885
886 =item B<get_all_metaclasses>
887
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.
890
891 =item B<get_all_metaclass_instances>
892
893 This will return an array of all the metaclass instances that have
894 been cached by B<Class::MOP::Class>.
895
896 =item B<get_all_metaclass_names>
897
898 This will return an array of all the metaclass names that have
899 been cached by B<Class::MOP::Class>.
900
901 =item B<get_metaclass_by_name ($name)>
902
903 This will return a cached B<Class::MOP::Class> instance of nothing
904 if no metaclass exist by that C<$name>.
905
906 =item B<store_metaclass_by_name ($name, $meta)>
907
908 This will store a metaclass in the cache at the supplied C<$key>.
909
910 =item B<weaken_metaclass ($name)>
911
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>.
915
916 =item B<does_metaclass_exist ($name)>
917
918 This will return true of there exists a metaclass stored in the 
919 C<$name> key and return false otherwise.
920
921 =item B<remove_metaclass_by_name ($name)>
922
923 This will remove a the metaclass stored in the C<$name> key.
924
925 =back
926
927 =head1 SEE ALSO
928
929 =head2 Books
930
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.
935
936 =over 4
937
938 =item "The Art of the Meta Object Protocol"
939
940 =item "Advances in Object-Oriented Metalevel Architecture and Reflection"
941
942 =item "Putting MetaClasses to Work"
943
944 =item "Smalltalk: The Language"
945
946 =back
947
948 =head2 Papers
949
950 =over 4
951
952 =item Uniform and safe metaclass composition
953
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.
958
959 L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
960
961 =item Safe Metaclass Programming
962
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.
966
967 L<http://citeseer.ist.psu.edu/37617.html>
968
969 =back
970
971 =head2 Prior Art
972
973 =over 4
974
975 =item The Perl 6 MetaModel work in the Pugs project
976
977 =over 4
978
979 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
980
981 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
982
983 =back
984
985 =back
986
987 =head2 Articles
988
989 =over 4
990
991 =item CPAN Module Review of Class::MOP
992
993 L<http://www.oreillynet.com/onlamp/blog/2006/06/cpan_module_review_classmop.html>
994
995 =back
996
997 =head1 SIMILAR MODULES
998
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.
1005
1006 =head1 BUGS
1007
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
1010 to cpan-RT.
1011
1012 =head1 ACKNOWLEDGEMENTS
1013
1014 =over 4
1015
1016 =item Rob Kinyon
1017
1018 Thanks to Rob for actually getting the development of this module kick-started.
1019
1020 =back
1021
1022 =head1 AUTHORS
1023
1024 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1025
1026 B<with contributions from:>
1027
1028 Brandon (blblack) Black
1029
1030 Guillermo (groditi) Roditi
1031
1032 Matt (mst) Trout
1033
1034 Rob (robkinyon) Kinyon
1035
1036 Yuval (nothingmuch) Kogman
1037
1038 Scott (konobi) McWhirter
1039
1040 =head1 COPYRIGHT AND LICENSE
1041
1042 Copyright 2006-2008 by Infinity Interactive, Inc.
1043
1044 L<http://www.iinteractive.com>
1045
1046 This library is free software; you can redistribute it and/or modify
1047 it under the same terms as Perl itself.
1048
1049 =cut