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