File Coverage

blib/lib/Class/MOP.pm
Criterion Covered Total %
statement 70 70 100.0
branch 5 6 83.3
condition 2 3 66.6
subroutine 30 30 100.0
pod 10 13 76.9
total 117 122 95.9


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