Addition of load_one_class_of, to allow does method in Moose to be made quicker.
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
1
2 package Class::MOP;
3
4 use strict;
5 use warnings;
6
7 use 5.008;
8
9 use MRO::Compat;
10
11 use Carp          'confess';
12 use Scalar::Util  'weaken';
13
14
15 use Class::MOP::Class;
16 use Class::MOP::Attribute;
17 use Class::MOP::Method;
18
19 use Class::MOP::Immutable;
20
21 BEGIN {
22     *IS_RUNNING_ON_5_10 = ($] < 5.009_005) 
23         ? sub () { 0 }
24         : sub () { 1 };    
25
26     *HAVE_ISAREV = defined(&mro::get_isarev)
27         ? sub () { 1 }
28         : sub () { 1 };
29
30     # this is either part of core or set up appropriately by MRO::Compat
31     *check_package_cache_flag = \&mro::get_pkg_gen;
32 }
33
34 our $VERSION   = '0.67';
35 our $XS_VERSION = $VERSION;
36 $VERSION = eval $VERSION;
37 our $AUTHORITY = 'cpan:STEVAN';    
38     
39 # after that everything is loaded, if we're allowed try to load faster XS
40 # versions of various things
41 _try_load_xs() or _load_pure_perl();
42
43 sub _try_load_xs {
44     return if $ENV{CLASS_MOP_NO_XS};
45
46     my $e = do {
47         local $@;
48         eval {
49             require XSLoader;
50             # just doing this - no warnings 'redefine' - doesn't work
51             # for some reason
52             local $^W = 0;
53             __PACKAGE__->XSLoader::load($XS_VERSION);
54
55             require Sub::Name;
56             Sub::Name->import(qw(subname));
57
58             require Devel::GlobalDestruction;
59             Devel::GlobalDestruction->import("in_global_destruction");
60         };
61         $@;
62     };
63
64     die $e if $e && $e !~ /object version|loadable object/;
65
66     return $e ? 0 : 1;
67 }
68
69 sub _load_pure_perl {
70     require Sub::Identify;
71     Sub::Identify->import('get_code_info');
72
73     *subname = sub { $_[1] };
74     *in_global_destruction = sub () { !1 }
75 }
76
77
78 {
79     # Metaclasses are singletons, so we cache them here.
80     # there is no need to worry about destruction though
81     # because they should die only when the program dies.
82     # After all, do package definitions even get reaped?
83     my %METAS;
84
85     # means of accessing all the metaclasses that have
86     # been initialized thus far (for mugwumps obj browser)
87     sub get_all_metaclasses         {        %METAS         }
88     sub get_all_metaclass_instances { values %METAS         }
89     sub get_all_metaclass_names     { keys   %METAS         }
90     sub get_metaclass_by_name       { $METAS{$_[0]}         }
91     sub store_metaclass_by_name     { $METAS{$_[0]} = $_[1] }
92     sub weaken_metaclass            { weaken($METAS{$_[0]}) }
93     sub does_metaclass_exist        { exists $METAS{$_[0]} && defined $METAS{$_[0]} }
94     sub remove_metaclass_by_name    { $METAS{$_[0]} = undef }
95
96     # NOTE:
97     # We only cache metaclasses, meaning instances of
98     # Class::MOP::Class. We do not cache instance of
99     # Class::MOP::Package or Class::MOP::Module. Mostly
100     # because I don't yet see a good reason to do so.
101 }
102
103 sub load_one_class_of {
104     use List::Util qw/first/;
105     my @classes = @_;
106
107     foreach my $class (@classes) {
108         unless ( _is_valid_class_name($class) ) {
109             my $display = defined($class) ? $class : 'undef';
110             confess "Invalid class name ($display)";
111         }
112     }
113
114     my %exceptions;
115     my $name = first {
116         return $_ if is_class_loaded($_);
117         # require it
118         my $file = $_ . '.pm';
119         $file =~ s{::}{/}g;
120         my $e = do { local $@; eval { require($file) }; $@ };
121         if ($e) {
122             $exceptions{$_} = $e;
123             return;
124         }
125         else {
126             return $_;
127         }
128     } @classes;
129
130     if ($name) {
131          return get_metaclass_by_name($name) || $name;
132     }
133
134     # Could load no classes.
135     confess join("\n", 
136         map { sprintf("Could not load class (%s) because : %s", $_, $exceptions{$_}) } @classes 
137     ) if keys %exceptions;
138 }
139
140 sub load_class {
141     load_one_class_of($_[0]);
142 }
143
144 sub _is_valid_class_name {
145     my $class = shift;
146
147     return 0 if ref($class);
148     return 0 unless defined($class);
149     return 0 unless length($class);
150
151     return 1 if $class =~ /^\w+(?:::\w+)*$/;
152
153     return 0;
154 }
155
156 sub is_class_loaded {
157     my $class = shift;
158
159     return 0 if ref($class) || !defined($class) || !length($class);
160
161     # walk the symbol table tree to avoid autovififying
162     # \*{${main::}{"Foo::"}} == \*main::Foo::
163
164     my $pack = \*::;
165     foreach my $part (split('::', $class)) {
166         return 0 unless exists ${$$pack}{"${part}::"};
167         $pack = \*{${$$pack}{"${part}::"}};
168     }
169
170     # check for $VERSION or @ISA
171     return 1 if exists ${$$pack}{VERSION}
172              && defined *{${$$pack}{VERSION}}{SCALAR};
173     return 1 if exists ${$$pack}{ISA}
174              && defined *{${$$pack}{ISA}}{ARRAY};
175
176     # check for any method
177     foreach ( keys %{$$pack} ) {
178         next if substr($_, -2, 2) eq '::';
179
180         my $glob = ${$$pack}{$_} || next;
181
182         # constant subs
183         if ( IS_RUNNING_ON_5_10 ) {
184             return 1 if ref $glob eq 'SCALAR';
185         }
186
187         return 1 if defined *{$glob}{CODE};
188     }
189
190     # fail
191     return 0;
192 }
193
194
195 ## ----------------------------------------------------------------------------
196 ## Setting up our environment ...
197 ## ----------------------------------------------------------------------------
198 ## Class::MOP needs to have a few things in the global perl environment so
199 ## that it can operate effectively. Those things are done here.
200 ## ----------------------------------------------------------------------------
201
202 # ... nothing yet actually ;)
203
204 ## ----------------------------------------------------------------------------
205 ## Bootstrapping
206 ## ----------------------------------------------------------------------------
207 ## The code below here is to bootstrap our MOP with itself. This is also
208 ## sometimes called "tying the knot". By doing this, we make it much easier
209 ## to extend the MOP through subclassing and such since now you can use the
210 ## MOP itself to extend itself.
211 ##
212 ## Yes, I know, thats weird and insane, but it's a good thing, trust me :)
213 ## ----------------------------------------------------------------------------
214
215 # We need to add in the meta-attributes here so that
216 # any subclass of Class::MOP::* will be able to
217 # inherit them using &construct_instance
218
219 ## --------------------------------------------------------
220 ## Class::MOP::Package
221
222 Class::MOP::Package->meta->add_attribute(
223     Class::MOP::Attribute->new('package' => (
224         reader   => {
225             # NOTE: we need to do this in order
226             # for the instance meta-object to
227             # not fall into meta-circular death
228             #
229             # we just alias the original method
230             # rather than re-produce it here
231             'name' => \&Class::MOP::Package::name
232         },
233     ))
234 );
235
236 Class::MOP::Package->meta->add_attribute(
237     Class::MOP::Attribute->new('namespace' => (
238         reader => {
239             # NOTE:
240             # we just alias the original method
241             # rather than re-produce it here
242             'namespace' => \&Class::MOP::Package::namespace
243         },
244         init_arg => undef,
245         default  => sub { \undef }
246     ))
247 );
248
249 ## --------------------------------------------------------
250 ## Class::MOP::Module
251
252 # NOTE:
253 # yeah this is kind of stretching things a bit,
254 # but truthfully the version should be an attribute
255 # of the Module, the weirdness comes from having to
256 # stick to Perl 5 convention and store it in the
257 # $VERSION package variable. Basically if you just
258 # squint at it, it will look how you want it to look.
259 # Either as a package variable, or as a attribute of
260 # the metaclass, isn't abstraction great :)
261
262 Class::MOP::Module->meta->add_attribute(
263     Class::MOP::Attribute->new('version' => (
264         reader => {
265             # NOTE:
266             # we just alias the original method
267             # rather than re-produce it here
268             'version' => \&Class::MOP::Module::version
269         },
270         init_arg => undef,
271         default  => sub { \undef }
272     ))
273 );
274
275 # NOTE:
276 # By following the same conventions as version here,
277 # we are opening up the possibility that people can
278 # use the $AUTHORITY in non-Class::MOP modules as
279 # well.
280
281 Class::MOP::Module->meta->add_attribute(
282     Class::MOP::Attribute->new('authority' => (
283         reader => {
284             # NOTE:
285             # we just alias the original method
286             # rather than re-produce it here
287             'authority' => \&Class::MOP::Module::authority
288         },
289         init_arg => undef,
290         default  => sub { \undef }
291     ))
292 );
293
294 ## --------------------------------------------------------
295 ## Class::MOP::Class
296
297 Class::MOP::Class->meta->add_attribute(
298     Class::MOP::Attribute->new('attributes' => (
299         reader   => {
300             # NOTE: we need to do this in order
301             # for the instance meta-object to
302             # not fall into meta-circular death
303             #
304             # we just alias the original method
305             # rather than re-produce it here
306             'get_attribute_map' => \&Class::MOP::Class::get_attribute_map
307         },
308         default  => sub { {} }
309     ))
310 );
311
312 Class::MOP::Class->meta->add_attribute(
313     Class::MOP::Attribute->new('methods' => (
314         reader   => {
315             # NOTE:
316             # we just alias the original method
317             # rather than re-produce it here
318             'get_method_map' => \&Class::MOP::Class::get_method_map
319         },
320         default => sub { {} }
321     ))
322 );
323
324 Class::MOP::Class->meta->add_attribute(
325     Class::MOP::Attribute->new('superclasses' => (
326         accessor => {
327             # NOTE:
328             # we just alias the original method
329             # rather than re-produce it here
330             'superclasses' => \&Class::MOP::Class::superclasses
331         },
332         init_arg => undef,
333         default  => sub { \undef }
334     ))
335 );
336
337 Class::MOP::Class->meta->add_attribute(
338     Class::MOP::Attribute->new('attribute_metaclass' => (
339         reader   => {
340             # NOTE:
341             # we just alias the original method
342             # rather than re-produce it here
343             'attribute_metaclass' => \&Class::MOP::Class::attribute_metaclass
344         },
345         default  => 'Class::MOP::Attribute',
346     ))
347 );
348
349 Class::MOP::Class->meta->add_attribute(
350     Class::MOP::Attribute->new('method_metaclass' => (
351         reader   => {
352             # NOTE:
353             # we just alias the original method
354             # rather than re-produce it here
355             'method_metaclass' => \&Class::MOP::Class::method_metaclass
356         },
357         default  => 'Class::MOP::Method',
358     ))
359 );
360
361 Class::MOP::Class->meta->add_attribute(
362     Class::MOP::Attribute->new('instance_metaclass' => (
363         reader   => {
364             # NOTE: we need to do this in order
365             # for the instance meta-object to
366             # not fall into meta-circular death
367             #
368             # we just alias the original method
369             # rather than re-produce it here
370             'instance_metaclass' => \&Class::MOP::Class::instance_metaclass
371         },
372         default  => 'Class::MOP::Instance',
373     ))
374 );
375
376 # NOTE:
377 # we don't actually need to tie the knot with
378 # Class::MOP::Class here, it is actually handled
379 # within Class::MOP::Class itself in the
380 # construct_class_instance method.
381
382 ## --------------------------------------------------------
383 ## Class::MOP::Attribute
384
385 Class::MOP::Attribute->meta->add_attribute(
386     Class::MOP::Attribute->new('name' => (
387         reader   => {
388             # NOTE: we need to do this in order
389             # for the instance meta-object to
390             # not fall into meta-circular death
391             #
392             # we just alias the original method
393             # rather than re-produce it here
394             'name' => \&Class::MOP::Attribute::name
395         }
396     ))
397 );
398
399 Class::MOP::Attribute->meta->add_attribute(
400     Class::MOP::Attribute->new('associated_class' => (
401         reader   => {
402             # NOTE: we need to do this in order
403             # for the instance meta-object to
404             # not fall into meta-circular death
405             #
406             # we just alias the original method
407             # rather than re-produce it here
408             'associated_class' => \&Class::MOP::Attribute::associated_class
409         }
410     ))
411 );
412
413 Class::MOP::Attribute->meta->add_attribute(
414     Class::MOP::Attribute->new('accessor' => (
415         reader    => { 'accessor'     => \&Class::MOP::Attribute::accessor     },
416         predicate => { 'has_accessor' => \&Class::MOP::Attribute::has_accessor },
417     ))
418 );
419
420 Class::MOP::Attribute->meta->add_attribute(
421     Class::MOP::Attribute->new('reader' => (
422         reader    => { 'reader'     => \&Class::MOP::Attribute::reader     },
423         predicate => { 'has_reader' => \&Class::MOP::Attribute::has_reader },
424     ))
425 );
426
427 Class::MOP::Attribute->meta->add_attribute(
428     Class::MOP::Attribute->new('initializer' => (
429         reader    => { 'initializer'     => \&Class::MOP::Attribute::initializer     },
430         predicate => { 'has_initializer' => \&Class::MOP::Attribute::has_initializer },
431     ))
432 );
433
434 Class::MOP::Attribute->meta->add_attribute(
435     Class::MOP::Attribute->new('writer' => (
436         reader    => { 'writer'     => \&Class::MOP::Attribute::writer     },
437         predicate => { 'has_writer' => \&Class::MOP::Attribute::has_writer },
438     ))
439 );
440
441 Class::MOP::Attribute->meta->add_attribute(
442     Class::MOP::Attribute->new('predicate' => (
443         reader    => { 'predicate'     => \&Class::MOP::Attribute::predicate     },
444         predicate => { 'has_predicate' => \&Class::MOP::Attribute::has_predicate },
445     ))
446 );
447
448 Class::MOP::Attribute->meta->add_attribute(
449     Class::MOP::Attribute->new('clearer' => (
450         reader    => { 'clearer'     => \&Class::MOP::Attribute::clearer     },
451         predicate => { 'has_clearer' => \&Class::MOP::Attribute::has_clearer },
452     ))
453 );
454
455 Class::MOP::Attribute->meta->add_attribute(
456     Class::MOP::Attribute->new('builder' => (
457         reader    => { 'builder'     => \&Class::MOP::Attribute::builder     },
458         predicate => { 'has_builder' => \&Class::MOP::Attribute::has_builder },
459     ))
460 );
461
462 Class::MOP::Attribute->meta->add_attribute(
463     Class::MOP::Attribute->new('init_arg' => (
464         reader    => { 'init_arg'     => \&Class::MOP::Attribute::init_arg     },
465         predicate => { 'has_init_arg' => \&Class::MOP::Attribute::has_init_arg },
466     ))
467 );
468
469 Class::MOP::Attribute->meta->add_attribute(
470     Class::MOP::Attribute->new('default' => (
471         # default has a custom 'reader' method ...
472         predicate => { 'has_default' => \&Class::MOP::Attribute::has_default },
473     ))
474 );
475
476 Class::MOP::Attribute->meta->add_attribute(
477     Class::MOP::Attribute->new('associated_methods' => (
478         reader   => { 'associated_methods' => \&Class::MOP::Attribute::associated_methods },
479         default  => sub { [] }
480     ))
481 );
482
483 Class::MOP::Attribute->meta->add_method('clone' => sub {
484     my $self  = shift;
485     $self->meta->clone_object($self, @_);
486 });
487
488 ## --------------------------------------------------------
489 ## Class::MOP::Method
490 Class::MOP::Method->meta->add_attribute(
491     Class::MOP::Attribute->new('body' => (
492         reader   => { 'body' => \&Class::MOP::Method::body },
493     ))
494 );
495
496 Class::MOP::Method->meta->add_attribute(
497     Class::MOP::Attribute->new('associated_metaclass' => (
498         reader   => { 'associated_metaclass' => \&Class::MOP::Method::associated_metaclass },
499     ))
500 );
501
502 Class::MOP::Method->meta->add_attribute(
503     Class::MOP::Attribute->new('package_name' => (
504         reader   => { 'package_name' => \&Class::MOP::Method::package_name },
505     ))
506 );
507
508 Class::MOP::Method->meta->add_attribute(
509     Class::MOP::Attribute->new('name' => (
510         reader   => { 'name' => \&Class::MOP::Method::name },
511     ))
512 );
513
514 Class::MOP::Method->meta->add_attribute(
515     Class::MOP::Attribute->new('original_method' => (
516         reader   => { 'original_method'      => \&Class::MOP::Method::original_method },
517         writer   => { '_set_original_method' => \&Class::MOP::Method::_set_original_method },
518     ))
519 );
520
521 Class::MOP::Method->meta->add_method('clone' => sub {
522     my $self  = shift;
523     my $clone = $self->meta->clone_object($self, @_);
524     $clone->_set_original_method($self);
525     return $clone;
526 });
527
528 ## --------------------------------------------------------
529 ## Class::MOP::Method::Wrapped
530
531 # NOTE:
532 # the way this item is initialized, this
533 # really does not follow the standard
534 # practices of attributes, but we put
535 # it here for completeness
536 Class::MOP::Method::Wrapped->meta->add_attribute(
537     Class::MOP::Attribute->new('modifier_table')
538 );
539
540 ## --------------------------------------------------------
541 ## Class::MOP::Method::Generated
542
543 Class::MOP::Method::Generated->meta->add_attribute(
544     Class::MOP::Attribute->new('is_inline' => (
545         reader   => { 'is_inline' => \&Class::MOP::Method::Generated::is_inline },
546         default  => 0, 
547     ))
548 );
549
550 ## --------------------------------------------------------
551 ## Class::MOP::Method::Accessor
552
553 Class::MOP::Method::Accessor->meta->add_attribute(
554     Class::MOP::Attribute->new('attribute' => (
555         reader   => {
556             'associated_attribute' => \&Class::MOP::Method::Accessor::associated_attribute
557         },
558     ))
559 );
560
561 Class::MOP::Method::Accessor->meta->add_attribute(
562     Class::MOP::Attribute->new('accessor_type' => (
563         reader   => { 'accessor_type' => \&Class::MOP::Method::Accessor::accessor_type },
564     ))
565 );
566
567 ## --------------------------------------------------------
568 ## Class::MOP::Method::Constructor
569
570 Class::MOP::Method::Constructor->meta->add_attribute(
571     Class::MOP::Attribute->new('options' => (
572         reader   => {
573             'options' => \&Class::MOP::Method::Constructor::options
574         },
575         default  => sub { +{} }
576     ))
577 );
578
579 Class::MOP::Method::Constructor->meta->add_attribute(
580     Class::MOP::Attribute->new('associated_metaclass' => (
581         init_arg => "metaclass", # FIXME alias and rename
582         reader   => {
583             'associated_metaclass' => \&Class::MOP::Method::Constructor::associated_metaclass
584         },
585     ))
586 );
587
588 ## --------------------------------------------------------
589 ## Class::MOP::Instance
590
591 # NOTE:
592 # these don't yet do much of anything, but are just
593 # included for completeness
594
595 Class::MOP::Instance->meta->add_attribute(
596     Class::MOP::Attribute->new('associated_metaclass',
597         reader   => { associated_metaclass => \&Class::MOP::Instance::associated_metaclass },
598     ),
599 );
600
601 Class::MOP::Instance->meta->add_attribute(
602     Class::MOP::Attribute->new('_class_name',
603         init_arg => undef,
604         reader   => { _class_name => \&Class::MOP::Instance::_class_name },
605         #lazy     => 1, # not yet supported by Class::MOP but out our version does it anyway
606         #default  => sub { $_[0]->associated_metaclass->name },
607     ),
608 );
609
610 Class::MOP::Instance->meta->add_attribute(
611     Class::MOP::Attribute->new('attributes',
612         reader   => { attributes => \&Class::MOP::Instance::get_all_attributes },
613     ),
614 );
615
616 Class::MOP::Instance->meta->add_attribute(
617     Class::MOP::Attribute->new('slots',
618         reader   => { slots => \&Class::MOP::Instance::slots },
619     ),
620 );
621
622 Class::MOP::Instance->meta->add_attribute(
623     Class::MOP::Attribute->new('slot_hash',
624         reader   => { slot_hash => \&Class::MOP::Instance::slot_hash },
625     ),
626 );
627
628
629 # we need the meta instance of the meta instance to be created now, in order
630 # for the constructor to be able to use it
631 Class::MOP::Instance->meta->get_meta_instance;
632
633 # pretend the add_method never happenned. it hasn't yet affected anything
634 undef Class::MOP::Instance->meta->{_package_cache_flag};
635
636 ## --------------------------------------------------------
637 ## Now close all the Class::MOP::* classes
638
639 # NOTE:
640 # we don't need to inline the
641 # constructors or the accessors
642 # this only lengthens the compile
643 # time of the MOP, and gives us
644 # no actual benefits.
645
646 $_->meta->make_immutable(
647     inline_constructor  => 1,
648     replace_constructor => 1,
649     constructor_name    => "_new",
650     inline_accessors => 0,
651 ) for qw/
652     Class::MOP::Package
653     Class::MOP::Module
654     Class::MOP::Class
655
656     Class::MOP::Attribute
657     Class::MOP::Method
658     Class::MOP::Instance
659
660     Class::MOP::Object
661
662     Class::MOP::Method::Generated
663
664     Class::MOP::Method::Accessor
665     Class::MOP::Method::Constructor
666     Class::MOP::Method::Wrapped
667 /;
668
669 1;
670
671 __END__
672
673 =pod
674
675 =head1 NAME
676
677 Class::MOP - A Meta Object Protocol for Perl 5
678
679 =head1 DESCRIPTON
680
681 This module is a fully functioning meta object protocol for the
682 Perl 5 object system. It makes no attempt to change the behavior or
683 characteristics of the Perl 5 object system, only to create a
684 protocol for its manipulation and introspection.
685
686 That said, it does attempt to create the tools for building a rich
687 set of extensions to the Perl 5 object system. Every attempt has been
688 made for these tools to keep to the spirit of the Perl 5 object
689 system that we all know and love.
690
691 This documentation is admittedly sparse on details, as time permits
692 I will try to improve them. For now, I suggest looking at the items
693 listed in the L<SEE ALSO> section for more information. In particular
694 the book "The Art of the Meta Object Protocol" was very influential
695 in the development of this system.
696
697 =head2 What is a Meta Object Protocol?
698
699 A meta object protocol is an API to an object system.
700
701 To be more specific, it is a set of abstractions of the components of
702 an object system (typically things like; classes, object, methods,
703 object attributes, etc.). These abstractions can then be used to both
704 inspect and manipulate the object system which they describe.
705
706 It can be said that there are two MOPs for any object system; the
707 implicit MOP, and the explicit MOP. The implicit MOP handles things
708 like method dispatch or inheritance, which happen automatically as
709 part of how the object system works. The explicit MOP typically
710 handles the introspection/reflection features of the object system.
711 All object systems have implicit MOPs, without one, they would not
712 work. Explict MOPs however as less common, and depending on the
713 language can vary from restrictive (Reflection in Java or C#) to
714 wide open (CLOS is a perfect example).
715
716 =head2 Yet Another Class Builder!! Why?
717
718 This is B<not> a class builder so much as it is a I<class builder
719 B<builder>>. My intent is that an end user does not use this module
720 directly, but instead this module is used by module authors to
721 build extensions and features onto the Perl 5 object system.
722
723 =head2 Who is this module for?
724
725 This module is specifically for anyone who has ever created or
726 wanted to create a module for the Class:: namespace. The tools which
727 this module will provide will hopefully make it easier to do more
728 complex things with Perl 5 classes by removing such barriers as
729 the need to hack the symbol tables, or understand the fine details
730 of method dispatch.
731
732 =head2 What changes do I have to make to use this module?
733
734 This module was designed to be as unintrusive as possible. Many of
735 its features are accessible without B<any> change to your existsing
736 code at all. It is meant to be a compliment to your existing code and
737 not an intrusion on your code base. Unlike many other B<Class::>
738 modules, this module B<does not> require you subclass it, or even that
739 you C<use> it in within your module's package.
740
741 The only features which requires additions to your code are the
742 attribute handling and instance construction features, and these are
743 both completely optional features. The only reason for this is because
744 Perl 5's object system does not actually have these features built
745 in. More information about this feature can be found below.
746
747 =head2 A Note about Performance?
748
749 It is a common misconception that explict MOPs are performance drains.
750 But this is not a universal truth at all, it is an side-effect of
751 specific implementations. For instance, using Java reflection is much
752 slower because the JVM cannot take advantage of any compiler
753 optimizations, and the JVM has to deal with much more runtime type
754 information as well. Reflection in C# is marginally better as it was
755 designed into the language and runtime (the CLR). In contrast, CLOS
756 (the Common Lisp Object System) was built to support an explicit MOP,
757 and so performance is tuned for it.
758
759 This library in particular does it's absolute best to avoid putting
760 B<any> drain at all upon your code's performance. In fact, by itself
761 it does nothing to affect your existing code. So you only pay for
762 what you actually use.
763
764 =head2 About Metaclass compatibility
765
766 This module makes sure that all metaclasses created are both upwards
767 and downwards compatible. The topic of metaclass compatibility is
768 highly esoteric and is something only encountered when doing deep and
769 involved metaclass hacking. There are two basic kinds of metaclass
770 incompatibility; upwards and downwards.
771
772 Upwards metaclass compatibility means that the metaclass of a
773 given class is either the same as (or a subclass of) all of the
774 class's ancestors.
775
776 Downward metaclass compatibility means that the metaclasses of a
777 given class's anscestors are all either the same as (or a subclass
778 of) that metaclass.
779
780 Here is a diagram showing a set of two classes (C<A> and C<B>) and
781 two metaclasses (C<Meta::A> and C<Meta::B>) which have correct
782 metaclass compatibility both upwards and downwards.
783
784     +---------+     +---------+
785     | Meta::A |<----| Meta::B |      <....... (instance of  )
786     +---------+     +---------+      <------- (inherits from)
787          ^               ^
788          :               :
789     +---------+     +---------+
790     |    A    |<----|    B    |
791     +---------+     +---------+
792
793 As I said this is a highly esoteric topic and one you will only run
794 into if you do a lot of subclassing of B<Class::MOP::Class>. If you
795 are interested in why this is an issue see the paper
796 I<Uniform and safe metaclass composition> linked to in the
797 L<SEE ALSO> section of this document.
798
799 =head2 Using custom metaclasses
800
801 Always use the metaclass pragma when using a custom metaclass, this
802 will ensure the proper initialization order and not accidentely
803 create an incorrect type of metaclass for you. This is a very rare
804 problem, and one which can only occur if you are doing deep metaclass
805 programming. So in other words, don't worry about it.
806
807 =head1 PROTOCOLS
808
809 The protocol is divided into 4 main sub-protocols:
810
811 =over 4
812
813 =item The Class protocol
814
815 This provides a means of manipulating and introspecting a Perl 5
816 class. It handles all of symbol table hacking for you, and provides
817 a rich set of methods that go beyond simple package introspection.
818
819 See L<Class::MOP::Class> for more details.
820
821 =item The Attribute protocol
822
823 This provides a consistent represenation for an attribute of a
824 Perl 5 class. Since there are so many ways to create and handle
825 attributes in Perl 5 OO, this attempts to provide as much of a
826 unified approach as possible, while giving the freedom and
827 flexibility to subclass for specialization.
828
829 See L<Class::MOP::Attribute> for more details.
830
831 =item The Method protocol
832
833 This provides a means of manipulating and introspecting methods in
834 the Perl 5 object system. As with attributes, there are many ways to
835 approach this topic, so we try to keep it pretty basic, while still
836 making it possible to extend the system in many ways.
837
838 See L<Class::MOP::Method> for more details.
839
840 =item The Instance protocol
841
842 This provides a layer of abstraction for creating object instances. 
843 Since the other layers use this protocol, it is relatively easy to 
844 change the type of your instances from the default HASH ref to other
845 types of references. Several examples are provided in the F<examples/> 
846 directory included in this distribution.
847
848 See L<Class::MOP::Instance> for more details.
849
850 =back
851
852 =head1 FUNCTIONS
853
854 =head2 Constants
855
856 =over 4
857
858 =item I<IS_RUNNING_ON_5_10>
859
860 We set this constant depending on what version perl we are on, this 
861 allows us to take advantage of new 5.10 features and stay backwards 
862 compat.
863
864 =item I<HAVE_ISAREV>
865
866 Whether or not C<mro> provides C<get_isarev>, a much faster way to get all the
867 subclasses of a certain class.
868
869 =back
870
871 =head2 Utility functions
872
873 Note that these are all called as B<functions, not methods>.
874
875 =over 4
876
877 =item B<load_class ($class_name)>
878
879 This will load a given C<$class_name> and if it does not have an
880 already initialized metaclass, then it will intialize one for it.
881 This function can be used in place of tricks like 
882 C<eval "use $module"> or using C<require>.
883
884 =item B<load_one_class_of ($class_name, [$class_name, ...])>
885
886 This will attempt to load the list of classes given as parameters.
887 The first class successfully found or loaded will have it's metaclass
888 initialized (if needed) and returned. Subsequent classes to the first
889 loaded class will be ignored, and an exception will be thrown if none
890 of the supplied class names can be loaded.
891
892 =item B<is_class_loaded ($class_name)>
893
894 This will return a boolean depending on if the C<$class_name> has
895 been loaded.
896
897 NOTE: This does a basic check of the symbol table to try and
898 determine as best it can if the C<$class_name> is loaded, it
899 is probably correct about 99% of the time.
900
901 =item B<check_package_cache_flag ($pkg)>
902
903 B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
904
905 This will return an integer that is managed by C<Class::MOP::Class>
906 to determine if a module's symbol table has been altered. 
907
908 In Perl 5.10 or greater, this flag is package specific. However in 
909 versions prior to 5.10, this will use the C<PL_sub_generation> variable
910 which is not package specific. 
911
912 =item B<get_code_info ($code)>
913
914 B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
915
916 This function returns two values, the name of the package the C<$code> 
917 is from and the name of the C<$code> itself. This is used by several 
918 elements of the MOP to detemine where a given C<$code> reference is from.
919
920 =item B<subname ($name, $code)>
921
922 B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
923
924 If possible, we will load the L<Sub::Name> module and this will function 
925 as C<Sub::Name::subname> does, otherwise it will just return the C<$code>
926 argument.
927
928 =item B<in_global_destruction>
929
930 B<NOTE: DO NOT USE THIS FUNCTION, IT IS FOR INTERNAL USE ONLY!>
931
932 If L<Devel::GlobalDestruction> is available, this returns true under global
933 destruction.
934
935 Otherwise it's a constant returning false.
936
937 =back
938
939 =head2 Metaclass cache functions
940
941 Class::MOP holds a cache of metaclasses, the following are functions
942 (B<not methods>) which can be used to access that cache. It is not
943 recommended that you mess with this, bad things could happen. But if
944 you are brave and willing to risk it, go for it.
945
946 =over 4
947
948 =item B<get_all_metaclasses>
949
950 This will return an hash of all the metaclass instances that have
951 been cached by B<Class::MOP::Class> keyed by the package name.
952
953 =item B<get_all_metaclass_instances>
954
955 This will return an array of all the metaclass instances that have
956 been cached by B<Class::MOP::Class>.
957
958 =item B<get_all_metaclass_names>
959
960 This will return an array of all the metaclass names that have
961 been cached by B<Class::MOP::Class>.
962
963 =item B<get_metaclass_by_name ($name)>
964
965 This will return a cached B<Class::MOP::Class> instance of nothing
966 if no metaclass exist by that C<$name>.
967
968 =item B<store_metaclass_by_name ($name, $meta)>
969
970 This will store a metaclass in the cache at the supplied C<$key>.
971
972 =item B<weaken_metaclass ($name)>
973
974 In rare cases it is desireable to store a weakened reference in 
975 the metaclass cache. This function will weaken the reference to 
976 the metaclass stored in C<$name>.
977
978 =item B<does_metaclass_exist ($name)>
979
980 This will return true of there exists a metaclass stored in the 
981 C<$name> key and return false otherwise.
982
983 =item B<remove_metaclass_by_name ($name)>
984
985 This will remove a the metaclass stored in the C<$name> key.
986
987 =back
988
989 =head1 SEE ALSO
990
991 =head2 Books
992
993 There are very few books out on Meta Object Protocols and Metaclasses
994 because it is such an esoteric topic. The following books are really
995 the only ones I have found. If you know of any more, B<I<please>>
996 email me and let me know, I would love to hear about them.
997
998 =over 4
999
1000 =item "The Art of the Meta Object Protocol"
1001
1002 =item "Advances in Object-Oriented Metalevel Architecture and Reflection"
1003
1004 =item "Putting MetaClasses to Work"
1005
1006 =item "Smalltalk: The Language"
1007
1008 =back
1009
1010 =head2 Papers
1011
1012 =over 4
1013
1014 =item Uniform and safe metaclass composition
1015
1016 An excellent paper by the people who brought us the original Traits paper.
1017 This paper is on how Traits can be used to do safe metaclass composition,
1018 and offers an excellent introduction section which delves into the topic of
1019 metaclass compatibility.
1020
1021 L<http://www.iam.unibe.ch/~scg/Archive/Papers/Duca05ySafeMetaclassTrait.pdf>
1022
1023 =item Safe Metaclass Programming
1024
1025 This paper seems to precede the above paper, and propose a mix-in based
1026 approach as opposed to the Traits based approach. Both papers have similar
1027 information on the metaclass compatibility problem space.
1028
1029 L<http://citeseer.ist.psu.edu/37617.html>
1030
1031 =back
1032
1033 =head2 Prior Art
1034
1035 =over 4
1036
1037 =item The Perl 6 MetaModel work in the Pugs project
1038
1039 =over 4
1040
1041 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel>
1042
1043 =item L<http://svn.openfoundry.org/pugs/perl5/Perl6-ObjectSpace>
1044
1045 =back
1046
1047 =back
1048
1049 =head2 Articles
1050
1051 =over 4
1052
1053 =item CPAN Module Review of Class::MOP
1054
1055 L<http://www.oreillynet.com/onlamp/blog/2006/06/cpan_module_review_classmop.html>
1056
1057 =back
1058
1059 =head1 SIMILAR MODULES
1060
1061 As I have said above, this module is a class-builder-builder, so it is
1062 not the same thing as modules like L<Class::Accessor> and
1063 L<Class::MethodMaker>. That being said there are very few modules on CPAN
1064 with similar goals to this module. The one I have found which is most
1065 like this module is L<Class::Meta>, although it's philosophy and the MOP it
1066 creates are very different from this modules.
1067
1068 =head1 BUGS
1069
1070 All complex software has bugs lurking in it, and this module is no
1071 exception. If you find a bug please either email me, or add the bug
1072 to cpan-RT.
1073
1074 =head1 ACKNOWLEDGEMENTS
1075
1076 =over 4
1077
1078 =item Rob Kinyon
1079
1080 Thanks to Rob for actually getting the development of this module kick-started.
1081
1082 =back
1083
1084 =head1 AUTHORS
1085
1086 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1087
1088 B<with contributions from:>
1089
1090 Brandon (blblack) Black
1091
1092 Florian (rafl) Ragwitz
1093
1094 Guillermo (groditi) Roditi
1095
1096 Matt (mst) Trout
1097
1098 Rob (robkinyon) Kinyon
1099
1100 Yuval (nothingmuch) Kogman
1101
1102 Scott (konobi) McWhirter
1103
1104 =head1 COPYRIGHT AND LICENSE
1105
1106 Copyright 2006-2008 by Infinity Interactive, Inc.
1107
1108 L<http://www.iinteractive.com>
1109
1110 This library is free software; you can redistribute it and/or modify
1111 it under the same terms as Perl itself.
1112
1113 =cut