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