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