use X Protocol phrase in docs for each module
[gitmo/Class-MOP.git] / lib / Class / MOP / Class.pm
1
2 package Class::MOP::Class;
3
4 use strict;
5 use warnings;
6
7 use Class::MOP::Immutable;
8 use Class::MOP::Instance;
9 use Class::MOP::Method::Wrapped;
10
11 use Carp         'confess';
12 use Scalar::Util 'blessed', 'weaken';
13
14 our $VERSION   = '0.78';
15 $VERSION = eval $VERSION;
16 our $AUTHORITY = 'cpan:STEVAN';
17
18 use base 'Class::MOP::Module';
19
20 # Creation
21
22 sub initialize {
23     my $class = shift;
24
25     my $package_name;
26     
27     if ( @_ % 2 ) {
28         $package_name = shift;
29     } else {
30         my %options = @_;
31         $package_name = $options{package};
32     }
33
34     (defined $package_name && $package_name && !ref($package_name))
35         || confess "You must pass a package name and it cannot be blessed";
36
37     return Class::MOP::get_metaclass_by_name($package_name)
38         || $class->construct_class_instance(package => $package_name, @_);
39 }
40
41 # NOTE: (meta-circularity)
42 # this is a special form of &construct_instance
43 # (see below), which is used to construct class
44 # meta-object instances for any Class::MOP::*
45 # class. All other classes will use the more
46 # normal &construct_instance.
47 sub construct_class_instance {
48     my $class        = shift;
49     my $options      = @_ == 1 ? $_[0] : {@_};
50     my $package_name = $options->{package};
51     (defined $package_name && $package_name)
52         || confess "You must pass a package name";
53     # NOTE:
54     # return the metaclass if we have it cached,
55     # and it is still defined (it has not been
56     # reaped by DESTROY yet, which can happen
57     # annoyingly enough during global destruction)
58
59     if (defined(my $meta = Class::MOP::get_metaclass_by_name($package_name))) {
60         return $meta;
61     }
62
63     # NOTE:
64     # we need to deal with the possibility
65     # of class immutability here, and then
66     # get the name of the class appropriately
67     $class = (ref($class)
68                     ? ($class->is_immutable
69                         ? $class->get_mutable_metaclass_name()
70                         : ref($class))
71                     : $class);
72
73     # now create the metaclass
74     my $meta;
75     if ($class eq 'Class::MOP::Class') {
76         $meta = $class->_new($options);
77     }
78     else {
79         # NOTE:
80         # it is safe to use meta here because
81         # class will always be a subclass of
82         # Class::MOP::Class, which defines meta
83         $meta = $class->meta->construct_instance($options)
84     }
85
86     # and check the metaclass compatibility
87     $meta->check_metaclass_compatibility();  
88
89     Class::MOP::store_metaclass_by_name($package_name, $meta);
90
91     # NOTE:
92     # we need to weaken any anon classes
93     # so that they can call DESTROY properly
94     Class::MOP::weaken_metaclass($package_name) if $meta->is_anon_class;
95
96     $meta;
97 }
98
99 sub _new {
100     my $class = shift;
101     my $options = @_ == 1 ? $_[0] : {@_};
102
103     bless {
104         # inherited from Class::MOP::Package
105         'package' => $options->{package},
106
107         # NOTE:
108         # since the following attributes will
109         # actually be loaded from the symbol
110         # table, and actually bypass the instance
111         # entirely, we can just leave these things
112         # listed here for reference, because they
113         # should not actually have a value associated
114         # with the slot.
115         'namespace' => \undef,
116
117         # inherited from Class::MOP::Module
118         'version'   => \undef,
119         'authority' => \undef,
120
121         # defined in Class::MOP::Class
122         'superclasses' => \undef,
123
124         'methods'             => {},
125         'attributes'          => {},
126         'attribute_metaclass' => $options->{'attribute_metaclass'}
127             || 'Class::MOP::Attribute',
128         'method_metaclass' => $options->{'method_metaclass'}
129             || 'Class::MOP::Method',
130         'wrapped_method_metaclass' => $options->{'wrapped_method_metaclass'}
131             || 'Class::MOP::Method::Wrapped',
132         'instance_metaclass' => $options->{'instance_metaclass'}
133             || 'Class::MOP::Instance',
134     }, $class;
135 }
136
137 sub reset_package_cache_flag  { (shift)->{'_package_cache_flag'} = undef } 
138 sub update_package_cache_flag {
139     my $self = shift;
140     # NOTE:
141     # we can manually update the cache number 
142     # since we are actually adding the method
143     # to our cache as well. This avoids us 
144     # having to regenerate the method_map.
145     # - SL    
146     $self->{'_package_cache_flag'} = Class::MOP::check_package_cache_flag($self->name);    
147 }
148
149 sub check_metaclass_compatibility {
150     my $self = shift;
151
152     # this is always okay ...
153     return if ref($self)                eq 'Class::MOP::Class'   &&
154               $self->instance_metaclass eq 'Class::MOP::Instance';
155
156     my @class_list = $self->linearized_isa;
157     shift @class_list; # shift off $self->name
158
159     foreach my $superclass_name (@class_list) {
160         my $super_meta = Class::MOP::get_metaclass_by_name($superclass_name) || next;
161
162         # NOTE:
163         # we need to deal with the possibility
164         # of class immutability here, and then
165         # get the name of the class appropriately
166         my $super_meta_type
167             = $super_meta->is_immutable
168             ? $super_meta->get_mutable_metaclass_name()
169             : ref($super_meta);
170
171         ($self->isa($super_meta_type))
172             || confess $self->name . "->meta => (" . (ref($self)) . ")" .
173                        " is not compatible with the " .
174                        $superclass_name . "->meta => (" . ($super_meta_type)     . ")";
175         # NOTE:
176         # we also need to check that instance metaclasses
177         # are compatibile in the same the class.
178         ($self->instance_metaclass->isa($super_meta->instance_metaclass))
179             || confess $self->name . "->meta->instance_metaclass => (" . ($self->instance_metaclass) . ")" .
180                        " is not compatible with the " .
181                        $superclass_name . "->meta->instance_metaclass => (" . ($super_meta->instance_metaclass) . ")";
182     }
183 }
184
185 ## ANON classes
186
187 {
188     # NOTE:
189     # this should be sufficient, if you have a
190     # use case where it is not, write a test and
191     # I will change it.
192     my $ANON_CLASS_SERIAL = 0;
193
194     # NOTE:
195     # we need a sufficiently annoying prefix
196     # this should suffice for now, this is
197     # used in a couple of places below, so
198     # need to put it up here for now.
199     my $ANON_CLASS_PREFIX = 'Class::MOP::Class::__ANON__::SERIAL::';
200
201     sub is_anon_class {
202         my $self = shift;
203         no warnings 'uninitialized';
204         $self->name =~ /^$ANON_CLASS_PREFIX/;
205     }
206
207     sub create_anon_class {
208         my ($class, %options) = @_;
209         my $package_name = $ANON_CLASS_PREFIX . ++$ANON_CLASS_SERIAL;
210         return $class->create($package_name, %options);
211     }
212
213     # NOTE:
214     # this will only get called for
215     # anon-classes, all other calls
216     # are assumed to occur during
217     # global destruction and so don't
218     # really need to be handled explicitly
219     sub DESTROY {
220         my $self = shift;
221
222         return if Class::MOP::in_global_destruction(); # it'll happen soon anyway and this just makes things more complicated
223
224         no warnings 'uninitialized';
225         return unless $self->name =~ /^$ANON_CLASS_PREFIX/;
226         # Moose does a weird thing where it replaces the metaclass for
227         # class when fixing metaclass incompatibility. In that case,
228         # we don't want to clean out the namespace now. We can detect
229         # that because Moose will explicitly update the singleton
230         # cache in Class::MOP.
231         my $current_meta = Class::MOP::get_metaclass_by_name($self->name);
232         return if $current_meta ne $self;
233
234         my ($serial_id) = ($self->name =~ /^$ANON_CLASS_PREFIX(\d+)/);
235         no strict 'refs';
236         foreach my $key (keys %{$ANON_CLASS_PREFIX . $serial_id}) {
237             delete ${$ANON_CLASS_PREFIX . $serial_id}{$key};
238         }
239         delete ${'main::' . $ANON_CLASS_PREFIX}{$serial_id . '::'};
240     }
241
242 }
243
244 # creating classes with MOP ...
245
246 sub create {
247     my ( $class, @args ) = @_;
248
249     unshift @args, 'package' if @args % 2 == 1;
250
251     my (%options) = @args;
252     my $package_name = $options{package};
253
254     (ref $options{superclasses} eq 'ARRAY')
255         || confess "You must pass an ARRAY ref of superclasses"
256             if exists $options{superclasses};
257             
258     (ref $options{attributes} eq 'ARRAY')
259         || confess "You must pass an ARRAY ref of attributes"
260             if exists $options{attributes};      
261             
262     (ref $options{methods} eq 'HASH')
263         || confess "You must pass a HASH ref of methods"
264             if exists $options{methods};                  
265
266     $class->SUPER::create(%options);
267
268     my (%initialize_options) = @args;
269     delete @initialize_options{qw(
270         package
271         superclasses
272         attributes
273         methods
274         version
275         authority
276     )};
277     my $meta = $class->initialize( $package_name => %initialize_options );
278
279     # FIXME totally lame
280     $meta->add_method('meta' => sub {
281         $class->initialize(ref($_[0]) || $_[0]);
282     });
283
284     $meta->superclasses(@{$options{superclasses}})
285         if exists $options{superclasses};
286     # NOTE:
287     # process attributes first, so that they can
288     # install accessors, but locally defined methods
289     # can then overwrite them. It is maybe a little odd, but
290     # I think this should be the order of things.
291     if (exists $options{attributes}) {
292         foreach my $attr (@{$options{attributes}}) {
293             $meta->add_attribute($attr);
294         }
295     }
296     if (exists $options{methods}) {
297         foreach my $method_name (keys %{$options{methods}}) {
298             $meta->add_method($method_name, $options{methods}->{$method_name});
299         }
300     }
301     return $meta;
302 }
303
304 ## Attribute readers
305
306 # NOTE:
307 # all these attribute readers will be bootstrapped
308 # away in the Class::MOP bootstrap section
309
310 sub get_attribute_map        { $_[0]->{'attributes'}                  }
311 sub attribute_metaclass      { $_[0]->{'attribute_metaclass'}         }
312 sub method_metaclass         { $_[0]->{'method_metaclass'}            }
313 sub wrapped_method_metaclass { $_[0]->{'wrapped_method_metaclass'}    }
314 sub instance_metaclass       { $_[0]->{'instance_metaclass'}          }
315
316 # Instance Construction & Cloning
317
318 sub new_object {
319     my $class = shift;
320
321     # NOTE:
322     # we need to protect the integrity of the
323     # Class::MOP::Class singletons here, so we
324     # delegate this to &construct_class_instance
325     # which will deal with the singletons
326     return $class->construct_class_instance(@_)
327         if $class->name->isa('Class::MOP::Class');
328     return $class->construct_instance(@_);
329 }
330
331 sub construct_instance {
332     my $class = shift;
333     my $params = @_ == 1 ? $_[0] : {@_};
334     my $meta_instance = $class->get_meta_instance();
335     my $instance = $meta_instance->create_instance();
336     foreach my $attr ($class->compute_all_applicable_attributes()) {
337         $attr->initialize_instance_slot($meta_instance, $instance, $params);
338     }
339     # NOTE:
340     # this will only work for a HASH instance type
341     if ($class->is_anon_class) {
342         (Scalar::Util::reftype($instance) eq 'HASH')
343             || confess "Currently only HASH based instances are supported with instance of anon-classes";
344         # NOTE:
345         # At some point we should make this official
346         # as a reserved slot name, but right now I am
347         # going to keep it here.
348         # my $RESERVED_MOP_SLOT = '__MOP__';
349         $instance->{'__MOP__'} = $class;
350     }
351     return $instance;
352 }
353
354
355 sub get_meta_instance {
356     my $self = shift;
357     $self->{'_meta_instance'} ||= $self->create_meta_instance();
358 }
359
360 sub create_meta_instance {
361     my $self = shift;
362     
363     my $instance = $self->instance_metaclass->new(
364         associated_metaclass => $self,
365         attributes => [ $self->compute_all_applicable_attributes() ],
366     );
367
368     $self->add_meta_instance_dependencies()
369         if $instance->is_dependent_on_superclasses();
370
371     return $instance;
372 }
373
374 sub clone_object {
375     my $class    = shift;
376     my $instance = shift;
377     (blessed($instance) && $instance->isa($class->name))
378         || confess "You must pass an instance of the metaclass (" . (ref $class ? $class->name : $class) . "), not ($instance)";
379
380     # NOTE:
381     # we need to protect the integrity of the
382     # Class::MOP::Class singletons here, they
383     # should not be cloned.
384     return $instance if $instance->isa('Class::MOP::Class');
385     $class->clone_instance($instance, @_);
386 }
387
388 sub clone_instance {
389     my ($class, $instance, %params) = @_;
390     (blessed($instance))
391         || confess "You can only clone instances, ($instance) is not a blessed instance";
392     my $meta_instance = $class->get_meta_instance();
393     my $clone = $meta_instance->clone_instance($instance);
394     foreach my $attr ($class->compute_all_applicable_attributes()) {
395         if ( defined( my $init_arg = $attr->init_arg ) ) {
396             if (exists $params{$init_arg}) {
397                 $attr->set_value($clone, $params{$init_arg});
398             }
399         }
400     }
401     return $clone;
402 }
403
404 sub rebless_instance {
405     my ($self, $instance, %params) = @_;
406
407     my $old_metaclass;
408     if ($instance->can('meta')) {
409         ($instance->meta->isa('Class::MOP::Class'))
410             || confess 'Cannot rebless instance if ->meta is not an instance of Class::MOP::Class';
411         $old_metaclass = $instance->meta;
412     }
413     else {
414         $old_metaclass = $self->initialize(ref($instance));
415     }
416
417     my $meta_instance = $self->get_meta_instance();
418
419     $self->name->isa($old_metaclass->name)
420         || confess "You may rebless only into a subclass of (". $old_metaclass->name ."), of which (". $self->name .") isn't.";
421
422     # rebless!
423     # we use $_[1] here because of t/306_rebless_overload.t regressions on 5.8.8
424     $meta_instance->rebless_instance_structure($_[1], $self);
425
426     foreach my $attr ( $self->compute_all_applicable_attributes ) {
427         if ( $attr->has_value($instance) ) {
428             if ( defined( my $init_arg = $attr->init_arg ) ) {
429                 $params{$init_arg} = $attr->get_value($instance)
430                     unless exists $params{$init_arg};
431             } 
432             else {
433                 $attr->set_value($instance, $attr->get_value($instance));
434             }
435         }
436     }
437
438     foreach my $attr ($self->compute_all_applicable_attributes) {
439         $attr->initialize_instance_slot($meta_instance, $instance, \%params);
440     }
441     
442     $instance;
443 }
444
445 # Inheritance
446
447 sub superclasses {
448     my $self     = shift;
449     my $var_spec = { sigil => '@', type => 'ARRAY', name => 'ISA' };
450     if (@_) {
451         my @supers = @_;
452         @{$self->get_package_symbol($var_spec)} = @supers;
453
454         # NOTE:
455         # on 5.8 and below, we need to call
456         # a method to get Perl to detect
457         # a cycle in the class hierarchy
458         my $class = $self->name;
459         $class->isa($class);
460
461         # NOTE:
462         # we need to check the metaclass
463         # compatibility here so that we can
464         # be sure that the superclass is
465         # not potentially creating an issues
466         # we don't know about
467
468         $self->check_metaclass_compatibility();
469         $self->update_meta_instance_dependencies();
470     }
471     @{$self->get_package_symbol($var_spec)};
472 }
473
474 sub subclasses {
475     my $self = shift;
476
477     my $super_class = $self->name;
478
479     if ( Class::MOP::HAVE_ISAREV() ) {
480         return @{ $super_class->mro::get_isarev() };
481     } else {
482         my @derived_classes;
483
484         my $find_derived_classes;
485         $find_derived_classes = sub {
486             my ($outer_class) = @_;
487
488             my $symbol_table_hashref = do { no strict 'refs'; \%{"${outer_class}::"} };
489
490             SYMBOL:
491             for my $symbol ( keys %$symbol_table_hashref ) {
492                 next SYMBOL if $symbol !~ /\A (\w+):: \z/x;
493                 my $inner_class = $1;
494
495                 next SYMBOL if $inner_class eq 'SUPER';    # skip '*::SUPER'
496
497                 my $class =
498                 $outer_class
499                 ? "${outer_class}::$inner_class"
500                 : $inner_class;
501
502                 if ( $class->isa($super_class) and $class ne $super_class ) {
503                     push @derived_classes, $class;
504                 }
505
506                 next SYMBOL if $class eq 'main';           # skip 'main::*'
507
508                 $find_derived_classes->($class);
509             }
510         };
511
512         my $root_class = q{};
513         $find_derived_classes->($root_class);
514
515         undef $find_derived_classes;
516
517         @derived_classes = sort { $a->isa($b) ? 1 : $b->isa($a) ? -1 : 0 } @derived_classes;
518
519         return @derived_classes;
520     }
521 }
522
523
524 sub linearized_isa {
525     return @{ mro::get_linear_isa( (shift)->name ) };
526 }
527
528 sub class_precedence_list {
529     my $self = shift;
530     my $name = $self->name;
531
532     unless (Class::MOP::IS_RUNNING_ON_5_10()) { 
533         # NOTE:
534         # We need to check for circular inheritance here
535         # if we are are not on 5.10, cause 5.8 detects it 
536         # late. This will do nothing if all is well, and 
537         # blow up otherwise. Yes, it's an ugly hack, better
538         # suggestions are welcome.        
539         # - SL
540         ($name || return)->isa('This is a test for circular inheritance') 
541     }
542
543     # if our mro is c3, we can 
544     # just grab the linear_isa
545     if (mro::get_mro($name) eq 'c3') {
546         return @{ mro::get_linear_isa($name) }
547     }
548     else {
549         # NOTE:
550         # we can't grab the linear_isa for dfs
551         # since it has all the duplicates 
552         # already removed.
553         return (
554             $name,
555             map {
556                 $self->initialize($_)->class_precedence_list()
557             } $self->superclasses()
558         );
559     }
560 }
561
562 ## Methods
563
564 sub wrap_method_body {
565     my ( $self, %args ) = @_;
566
567     ('CODE' eq ref $args{body})
568         || confess "Your code block must be a CODE reference";
569
570     $self->method_metaclass->wrap(
571         package_name => $self->name,
572         %args,
573     );
574 }
575
576 sub add_method {
577     my ($self, $method_name, $method) = @_;
578     (defined $method_name && $method_name)
579         || confess "You must define a method name";
580
581     my $body;
582     if (blessed($method)) {
583         $body = $method->body;
584         if ($method->package_name ne $self->name) {
585             $method = $method->clone(
586                 package_name => $self->name,
587                 name         => $method_name            
588             ) if $method->can('clone');
589         }
590     }
591     else {
592         $body = $method;
593         $method = $self->wrap_method_body( body => $body, name => $method_name );
594     }
595
596     $method->attach_to_class($self);
597
598     # This used to call get_method_map, which meant we would build all
599     # the method objects for the class just because we added one
600     # method. This is hackier, but quicker too.
601     $self->{methods}{$method_name} = $method;
602     
603     my $full_method_name = ($self->name . '::' . $method_name);    
604     $self->add_package_symbol(
605         { sigil => '&', type => 'CODE', name => $method_name }, 
606         Class::MOP::subname($full_method_name => $body)
607     );
608 }
609
610 {
611     my $fetch_and_prepare_method = sub {
612         my ($self, $method_name) = @_;
613         my $wrapped_metaclass = $self->wrapped_method_metaclass;
614         # fetch it locally
615         my $method = $self->get_method($method_name);
616         # if we dont have local ...
617         unless ($method) {
618             # try to find the next method
619             $method = $self->find_next_method_by_name($method_name);
620             # die if it does not exist
621             (defined $method)
622                 || confess "The method '$method_name' was not found in the inheritance hierarchy for " . $self->name;
623             # and now make sure to wrap it
624             # even if it is already wrapped
625             # because we need a new sub ref
626             $method = $wrapped_metaclass->wrap($method);
627         }
628         else {
629             # now make sure we wrap it properly
630             $method = $wrapped_metaclass->wrap($method)
631                 unless $method->isa($wrapped_metaclass);
632         }
633         $self->add_method($method_name => $method);
634         return $method;
635     };
636
637     sub add_before_method_modifier {
638         my ($self, $method_name, $method_modifier) = @_;
639         (defined $method_name && $method_name)
640             || confess "You must pass in a method name";
641         my $method = $fetch_and_prepare_method->($self, $method_name);
642         $method->add_before_modifier(
643             Class::MOP::subname(':before' => $method_modifier)
644         );
645     }
646
647     sub add_after_method_modifier {
648         my ($self, $method_name, $method_modifier) = @_;
649         (defined $method_name && $method_name)
650             || confess "You must pass in a method name";
651         my $method = $fetch_and_prepare_method->($self, $method_name);
652         $method->add_after_modifier(
653             Class::MOP::subname(':after' => $method_modifier)
654         );
655     }
656
657     sub add_around_method_modifier {
658         my ($self, $method_name, $method_modifier) = @_;
659         (defined $method_name && $method_name)
660             || confess "You must pass in a method name";
661         my $method = $fetch_and_prepare_method->($self, $method_name);
662         $method->add_around_modifier(
663             Class::MOP::subname(':around' => $method_modifier)
664         );
665     }
666
667     # NOTE:
668     # the methods above used to be named like this:
669     #    ${pkg}::${method}:(before|after|around)
670     # but this proved problematic when using one modifier
671     # to wrap multiple methods (something which is likely
672     # to happen pretty regularly IMO). So instead of naming
673     # it like this, I have chosen to just name them purely
674     # with their modifier names, like so:
675     #    :(before|after|around)
676     # The fact is that in a stack trace, it will be fairly
677     # evident from the context what method they are attached
678     # to, and so don't need the fully qualified name.
679 }
680
681 sub alias_method {
682     my $self = shift;
683
684     $self->add_method(@_);
685 }
686
687 sub has_method {
688     my ($self, $method_name) = @_;
689     (defined $method_name && $method_name)
690         || confess "You must define a method name";
691
692     exists $self->{methods}{$method_name} || exists $self->get_method_map->{$method_name};
693 }
694
695 sub get_method {
696     my ($self, $method_name) = @_;
697     (defined $method_name && $method_name)
698         || confess "You must define a method name";
699
700     return $self->{methods}{$method_name} || $self->get_method_map->{$method_name};
701 }
702
703 sub remove_method {
704     my ($self, $method_name) = @_;
705     (defined $method_name && $method_name)
706         || confess "You must define a method name";
707
708     my $removed_method = delete $self->get_method_map->{$method_name};
709     
710     $self->remove_package_symbol(
711         { sigil => '&', type => 'CODE', name => $method_name }
712     );
713
714     $removed_method->detach_from_class if $removed_method;
715
716     $self->update_package_cache_flag; # still valid, since we just removed the method from the map
717
718     return $removed_method;
719 }
720
721 sub get_method_list {
722     my $self = shift;
723     keys %{$self->get_method_map};
724 }
725
726 sub find_method_by_name {
727     my ($self, $method_name) = @_;
728     (defined $method_name && $method_name)
729         || confess "You must define a method name to find";
730     foreach my $class ($self->linearized_isa) {
731         # fetch the meta-class ...
732         my $meta = $self->initialize($class);
733         return $meta->get_method($method_name)
734             if $meta->has_method($method_name);
735     }
736     return;
737 }
738
739 sub get_all_methods {
740     my $self = shift;
741     my %methods = map { %{ $self->initialize($_)->get_method_map } } reverse $self->linearized_isa;
742     return values %methods;
743 }
744
745 # compatibility
746 sub compute_all_applicable_methods {
747     return map {
748         {
749             name  => $_->name,
750             class => $_->package_name,
751             code  => $_, # sigh, overloading
752         },
753     } shift->get_all_methods(@_);
754 }
755
756 sub get_all_method_names {
757     my $self = shift;
758     my %uniq;
759     grep { $uniq{$_}++ == 0 } map { $_->name } $self->get_all_methods;
760 }
761
762 sub find_all_methods_by_name {
763     my ($self, $method_name) = @_;
764     (defined $method_name && $method_name)
765         || confess "You must define a method name to find";
766     my @methods;
767     foreach my $class ($self->linearized_isa) {
768         # fetch the meta-class ...
769         my $meta = $self->initialize($class);
770         push @methods => {
771             name  => $method_name,
772             class => $class,
773             code  => $meta->get_method($method_name)
774         } if $meta->has_method($method_name);
775     }
776     return @methods;
777 }
778
779 sub find_next_method_by_name {
780     my ($self, $method_name) = @_;
781     (defined $method_name && $method_name)
782         || confess "You must define a method name to find";
783     my @cpl = $self->linearized_isa;
784     shift @cpl; # discard ourselves
785     foreach my $class (@cpl) {
786         # fetch the meta-class ...
787         my $meta = $self->initialize($class);
788         return $meta->get_method($method_name)
789             if $meta->has_method($method_name);
790     }
791     return;
792 }
793
794 ## Attributes
795
796 sub add_attribute {
797     my $self      = shift;
798     # either we have an attribute object already
799     # or we need to create one from the args provided
800     my $attribute = blessed($_[0]) ? $_[0] : $self->attribute_metaclass->new(@_);
801     # make sure it is derived from the correct type though
802     ($attribute->isa('Class::MOP::Attribute'))
803         || confess "Your attribute must be an instance of Class::MOP::Attribute (or a subclass)";
804
805     # first we attach our new attribute
806     # because it might need certain information
807     # about the class which it is attached to
808     $attribute->attach_to_class($self);
809
810     # then we remove attributes of a conflicting
811     # name here so that we can properly detach
812     # the old attr object, and remove any
813     # accessors it would have generated
814     if ( $self->has_attribute($attribute->name) ) {
815         $self->remove_attribute($attribute->name);
816     } else {
817         $self->invalidate_meta_instances();
818     }
819
820     # then onto installing the new accessors
821     $self->get_attribute_map->{$attribute->name} = $attribute;
822
823     # invalidate package flag here
824     my $e = do { local $@; eval { $attribute->install_accessors() }; $@ };
825     if ( $e ) {
826         $self->remove_attribute($attribute->name);
827         die $e;
828     }
829
830     return $attribute;
831 }
832
833 sub update_meta_instance_dependencies {
834     my $self = shift;
835
836     if ( $self->{meta_instance_dependencies} ) {
837         return $self->add_meta_instance_dependencies;
838     }
839 }
840
841 sub add_meta_instance_dependencies {
842     my $self = shift;
843
844     $self->remove_meta_instance_dependencies;
845
846     my @attrs = $self->compute_all_applicable_attributes();
847
848     my %seen;
849     my @classes = grep { not $seen{$_->name}++ } map { $_->associated_class } @attrs;
850
851     foreach my $class ( @classes ) { 
852         $class->add_dependent_meta_instance($self);
853     }
854
855     $self->{meta_instance_dependencies} = \@classes;
856 }
857
858 sub remove_meta_instance_dependencies {
859     my $self = shift;
860
861     if ( my $classes = delete $self->{meta_instance_dependencies} ) {
862         foreach my $class ( @$classes ) {
863             $class->remove_dependent_meta_instance($self);
864         }
865
866         return $classes;
867     }
868
869     return;
870
871 }
872
873 sub add_dependent_meta_instance {
874     my ( $self, $metaclass ) = @_;
875     push @{ $self->{dependent_meta_instances} }, $metaclass;
876 }
877
878 sub remove_dependent_meta_instance {
879     my ( $self, $metaclass ) = @_;
880     my $name = $metaclass->name;
881     @$_ = grep { $_->name ne $name } @$_ for $self->{dependent_meta_instances};
882 }
883
884 sub invalidate_meta_instances {
885     my $self = shift;
886     $_->invalidate_meta_instance() for $self, @{ $self->{dependent_meta_instances} };
887 }
888
889 sub invalidate_meta_instance {
890     my $self = shift;
891     undef $self->{_meta_instance};
892 }
893
894 sub has_attribute {
895     my ($self, $attribute_name) = @_;
896     (defined $attribute_name && $attribute_name)
897         || confess "You must define an attribute name";
898     exists $self->get_attribute_map->{$attribute_name};
899 }
900
901 sub get_attribute {
902     my ($self, $attribute_name) = @_;
903     (defined $attribute_name && $attribute_name)
904         || confess "You must define an attribute name";
905     return $self->get_attribute_map->{$attribute_name}
906     # NOTE:
907     # this will return undef anyway, so no need ...
908     #    if $self->has_attribute($attribute_name);
909     #return;
910 }
911
912 sub remove_attribute {
913     my ($self, $attribute_name) = @_;
914     (defined $attribute_name && $attribute_name)
915         || confess "You must define an attribute name";
916     my $removed_attribute = $self->get_attribute_map->{$attribute_name};
917     return unless defined $removed_attribute;
918     delete $self->get_attribute_map->{$attribute_name};
919     $self->invalidate_meta_instances();
920     $removed_attribute->remove_accessors();
921     $removed_attribute->detach_from_class();
922     return $removed_attribute;
923 }
924
925 sub get_attribute_list {
926     my $self = shift;
927     keys %{$self->get_attribute_map};
928 }
929
930 sub get_all_attributes {
931     shift->compute_all_applicable_attributes(@_);
932 }
933
934 sub compute_all_applicable_attributes {
935     my $self = shift;
936     my %attrs = map { %{ $self->initialize($_)->get_attribute_map } } reverse $self->linearized_isa;
937     return values %attrs;
938 }
939
940 sub find_attribute_by_name {
941     my ($self, $attr_name) = @_;
942     foreach my $class ($self->linearized_isa) {
943         # fetch the meta-class ...
944         my $meta = $self->initialize($class);
945         return $meta->get_attribute($attr_name)
946             if $meta->has_attribute($attr_name);
947     }
948     return;
949 }
950
951 # check if we can reinitialize
952 sub is_pristine {
953     my $self = shift;
954
955     # if any local attr is defined
956     return if $self->get_attribute_list;
957
958     # or any non-declared methods
959     if ( my @methods = values %{ $self->get_method_map } ) {
960         my $metaclass = $self->method_metaclass;
961         foreach my $method ( @methods ) {
962             return if $method->isa("Class::MOP::Method::Generated");
963             # FIXME do we need to enforce this too? return unless $method->isa($metaclass);
964         }
965     }
966
967     return 1;
968 }
969
970 ## Class closing
971
972 sub is_mutable   { 1 }
973 sub is_immutable { 0 }
974
975 sub immutable_transformer { $_[0]->{immutable_transformer} }
976 sub _set_immutable_transformer { $_[0]->{immutable_transformer} = $_[1] }
977
978 {
979     my %Default_Immutable_Options = (
980         read_only   => [qw/superclasses/],
981         cannot_call => [
982             qw/
983                 add_method
984                 alias_method
985                 remove_method
986                 add_attribute
987                 remove_attribute
988                 remove_package_symbol
989                 /
990         ],
991         memoize => {
992             class_precedence_list => 'ARRAY',
993             # FIXME perl 5.10 memoizes this on its own, no need?
994             linearized_isa                    => 'ARRAY',
995             get_all_methods                   => 'ARRAY',
996             get_all_method_names              => 'ARRAY',
997             compute_all_applicable_attributes => 'ARRAY',
998             get_meta_instance                 => 'SCALAR',
999             get_method_map                    => 'SCALAR',
1000         },
1001
1002         # NOTE:
1003         # this is ugly, but so are typeglobs,
1004         # so whattayahgonnadoboutit
1005         # - SL
1006         wrapped => {
1007             add_package_symbol => sub {
1008                 my $original = shift;
1009                 confess "Cannot add package symbols to an immutable metaclass"
1010                     unless ( caller(2) )[3] eq
1011                     'Class::MOP::Package::get_package_symbol';
1012
1013                 # This is a workaround for a bug in 5.8.1 which thinks that
1014                 # goto $original->body
1015                 # is trying to go to a label
1016                 my $body = $original->body;
1017                 goto $body;
1018             },
1019         },
1020     );
1021
1022     sub make_immutable {
1023         my $self = shift;
1024
1025         return if $self->is_immutable;
1026
1027         my $transformer = $self->immutable_transformer
1028             || Class::MOP::Immutable->new(
1029             $self,
1030             %Default_Immutable_Options,
1031             @_
1032             );
1033
1034         $self->_set_immutable_transformer($transformer);
1035
1036         $transformer->make_metaclass_immutable;
1037     }
1038 }
1039
1040 sub make_mutable {
1041     my $self = shift;
1042
1043     return if $self->is_mutable;
1044
1045     $self->immutable_transformer->make_metaclass_mutable;
1046 }
1047
1048 1;
1049
1050 __END__
1051
1052 =pod
1053
1054 =head1 NAME
1055
1056 Class::MOP::Class - Class Meta Object
1057
1058 =head1 SYNOPSIS
1059
1060   # assuming that class Foo
1061   # has been defined, you can
1062
1063   # use this for introspection ...
1064
1065   # add a method to Foo ...
1066   Foo->meta->add_method( 'bar' => sub {...} )
1067
1068       # get a list of all the classes searched
1069       # the method dispatcher in the correct order
1070       Foo->meta->class_precedence_list()
1071
1072       # remove a method from Foo
1073       Foo->meta->remove_method('bar');
1074
1075   # or use this to actually create classes ...
1076
1077   Class::MOP::Class->create(
1078       'Bar' => (
1079           version      => '0.01',
1080           superclasses => ['Foo'],
1081           attributes   => [
1082               Class::MOP:: : Attribute->new('$bar'),
1083               Class::MOP:: : Attribute->new('$baz'),
1084           ],
1085           methods => {
1086               calculate_bar => sub {...},
1087               construct_baz => sub {...}
1088           }
1089       )
1090   );
1091
1092 =head1 DESCRIPTION
1093
1094 The Class Protocol is the largest and most complex part of the
1095 Class::MOP meta-object protocol. It controls the introspection and
1096 manipulation of Perl 5 classes, and it can create them as well. The
1097 best way to understand what this module can do, is to read the
1098 documentation for each of its methods.
1099
1100 =head1 INHERITANCE
1101
1102 C<Class::MOP::Class> is a subclass of L<Class::MOP::Module>.
1103
1104 =head1 METHODS
1105
1106 =head2 Class construction
1107
1108 These methods all create new C<Class::MOP::Class> objects. These
1109 objects can represent existing classes, or they can be used to create
1110 new classes from scratch.
1111
1112 The metaclass object for a given class is a singleton. If you attempt
1113 to create a metaclass for the same class twice, you will just get the
1114 existing object.
1115
1116 =over 4
1117
1118 =item B<< Class::MOP::Class->create($package_name, %options) >>
1119
1120 This method creates a new C<Class::MOP::Class> object with the given
1121 package name. It accepts a number of options.
1122
1123 =over 8
1124
1125 =item * version
1126
1127 An optional version number for the newly created package.
1128
1129 =item * authority
1130
1131 An optional authority for the newly created package.
1132
1133 =item * superclasses
1134
1135 An optional array reference of superclass names.
1136
1137 =item * methods
1138
1139 An optional hash reference of methods for the class. The keys of the
1140 hash reference are method names, and values are subroutine references.
1141
1142 =item * attributes
1143
1144 An optional array reference of attributes.
1145
1146 An attribute can be passed as an existing L<Class::MOP::Attribute>
1147 object, I<or> or as a hash reference of options which will be passed
1148 to the attribute metaclass's constructor.
1149
1150 =back
1151
1152 =item B<< Class::MOP::Class->create_anon_class(%options) >>
1153
1154 This method works just like C<< Class::MOP::Class->create >> but it
1155 creates an "anonymous" class. In fact, the class does have a name, but
1156 that name is a unique name generated internally by this module.
1157
1158 It accepts the same C<superclasses>, C<methods>, and C<attributes>
1159 parameters that C<create> accepts.
1160
1161 Anonymous classes are destroyed once the metaclass they are attached
1162 to goes out of scope, and will be removed from Perl's internal symbol
1163 table.
1164
1165 All instances of an anonymous class keep a special reference to the
1166 metaclass object, which prevents the metaclass from going out of scope
1167 while any instances exist.
1168
1169 This only works if the instance if based on a hash reference, however.
1170
1171 =item B<< Class::MOP::Class->initialize($package_name, %options) >>
1172
1173 This method will initialize a C<Class::MOP::Class> object for the
1174 named package. Unlike C<create>, this method I<will not> create a new
1175 class.
1176
1177 The purpose of this method is to retrieve a C<Class::MOP::Class>
1178 object for introspecting an existing class.
1179
1180 If an existing C<Class::MOP::Class> object exists for the named
1181 package, it will be returned, and any options provided will be
1182 ignored!
1183
1184 If the object does not yet exist, it will be created.
1185
1186 The valid options that can be passed to this method are
1187 C<attribute_metaclass>, C<method_metaclass>,
1188 C<wrapped_method_metaclass>, and C<instance_metaclass>. These are all
1189 optional, and default to the appropriate class in the C<Class::MOP>
1190 distribution.
1191
1192 =back
1193
1194 =head2 Object instance construction and cloning
1195
1196 These methods are all related to creating and/or cloning object
1197 instances.
1198
1199 =over 4
1200
1201 =item B<< $metaclass->clone_object($instance, %params) >>
1202
1203 This method clones an existing object instance. Any parameters you
1204 provide are will override existing attribute values in the object.
1205
1206 This is a convenience method for cloning an object instance, then
1207 blessing it into the appropriate package.
1208
1209 You could implement a clone method in your class, using this method:
1210
1211   sub clone {
1212       my ($self, %params) = @_;
1213       $self->meta->clone_object($self, %params);
1214   }
1215
1216 =item B<< $metaclass->rebless_instance($instance, %params) >>
1217
1218 This method changes the class of C<$instance> to the metaclass's class.
1219
1220 You can only rebless an instance into a subclass of its current
1221 class. If you pass any additional parameters, these will be treated
1222 like constructor parameters and used to initialize the object's
1223 attributes. Any existing attributes that are already set will be
1224 overwritten.
1225
1226 =item B<< $metaclass->new_object(%params) >>
1227
1228 This method is used to create a new object of the metaclass's
1229 class. Any parameters you provide are used to initialize the
1230 instance's attributes.
1231
1232 =item B<< $metaclass->instance_metaclass >>
1233
1234 Returns the class name of the instance metaclass, see
1235 L<Class::MOP::Instance> for more information on the instance
1236 metaclasses.
1237
1238 =item B<< $metaclass->get_meta_instance >>
1239
1240 Returns an instance of the C<instance_metaclass> to be used in the
1241 construction of a new instance of the class.
1242
1243 =back
1244
1245 =head2 Informational predicates
1246
1247 These are a few predicate methods for asking information about the
1248 class itself.
1249
1250 =over 4
1251
1252 =item B<< $metaclass->is_anon_class >>
1253
1254 This returns true if the class was created by calling C<<
1255 Class::MOP::Class->create_anon_class >>.
1256
1257 =item B<< $metaclass->is_mutable >>
1258
1259 This returns true if the class is still mutable.
1260
1261 =item B<< $metaclass->is_immutable >>
1262
1263 This returns true if the class has been made immutable.
1264
1265 =item B<< $metaclass->is_pristine >>
1266
1267 A class is I<not> pristine if it has non-inherited attributes or if it
1268 has any generated methods.
1269
1270 =back
1271
1272 =head2 Inheritance Relationships
1273
1274 =over 4
1275
1276 =item B<< $metaclass->superclasses(@superclasses) >>
1277
1278 This is a read-write accessor which represents the superclass
1279 relationships of the metaclass's class.
1280
1281 This is basically sugar around getting and setting C<@ISA>.
1282
1283 =item B<< $metaclass->class_precedence_list >>
1284
1285 This returns a list of all of the class's ancestor classes. The
1286 classes are returned in method dispatch order.
1287
1288 =item B<< $metaclass->linearized_isa >>
1289
1290 This returns a list based on C<class_precedence_list> but with all
1291 duplicates removed.
1292
1293 =item B<< $metaclass->subclasses >>
1294
1295 This returns a list of subclasses for this class.
1296
1297 =back
1298
1299 =head2 Method introspection and creation
1300
1301 These methods allow you to introspect a class's methods, as well as
1302 add, remove, or change methods.
1303
1304 Determining what is truly a method in a Perl 5 class requires some
1305 heuristics (aka guessing).
1306
1307 Methods defined outside the package with a fully qualified name (C<sub
1308 Package::name { ... }>) will be included. Similarly, methods named
1309 with a fully qualified name using L<Sub::Name> are also included.
1310
1311 However, we attempt to ignore imported functions.
1312
1313 Ultimately, we are using heuristics to determine what truly is a
1314 method in a class, and these heuristics may get the wrong answer in
1315 some edge cases. However, for most "normal" cases the heuristics work
1316 correctly.
1317
1318 =over 4
1319
1320 =item B<< $metaclass->get_method($method_name) >>
1321
1322 This will return a L<Class::MOP::Method> for the specified
1323 C<$method_name>. If the class does not have the specified method, it
1324 returns C<undef>
1325
1326 =item B<< $metaclass->has_method($method_name) >>
1327
1328 Returns a boolean indicating whether or not the class defines the
1329 named method. It does not include methods inherited from parent
1330 classes.
1331
1332 =item B<< $metaclass->get_method_map >>
1333
1334 Returns a hash reference representing the methods defined in this
1335 class. The keys are method names and the values are
1336 L<Class::MOP::Method> objects.
1337
1338 =item B<< $metaclass->get_method_list >>
1339
1340 This will return a list of method I<names> for all methods defined in
1341 this class.
1342
1343 =item B<< $metaclass->get_all_methods >>
1344
1345 This will traverse the inheritance hierarchy and return a list of all
1346 the L<Class::MOP::Method> objects for this class and its parents.
1347
1348 =item B<< $metaclass->find_method_by_name($method_name) >>
1349
1350 This will return a L<Class::MOP::Method> for the specified
1351 C<$method_name>. If the class does not have the specified method, it
1352 returns C<undef>
1353
1354 Unlike C<get_method>, this method I<will> look for the named method in
1355 superclasses.
1356
1357 =item B<< $metaclass->get_all_method_names >>
1358
1359 This will return a list of method I<names> for all of this class's
1360 methods, including inherited methods.
1361
1362 =item B<< $metaclass->find_all_methods_by_name($method_name) >>
1363
1364 This method looks for the named method in the class and all of its
1365 parents. It returns every matching method it finds in the inheritance
1366 tree, so it returns a list of methods.
1367
1368 Each method is returned as a hash reference with three keys. The keys
1369 are C<name>, C<class>, and C<code>. The C<code> key has a
1370 L<Class::MOP::Method> object as its value.
1371
1372 The list of methods is distinct.
1373
1374 =item B<< $metaclass->find_next_method_by_name($method_name) >>
1375
1376 This method returns the first method in any superclass matching the
1377 given name. It is effectively the method that C<SUPER::$method_name>
1378 would dispatch to.
1379
1380 =item B<< $metaclass->add_method($method_name, $method) >>
1381
1382 This method takes a method name and a subroutine reference, and adds
1383 the method to the class.
1384
1385 The subroutine reference can be a L<Class::MOP::Method>, and you are
1386 strongly encouraged to pass a meta method object instead of a code
1387 reference. If you do so, that object gets stored as part of the
1388 class's method map directly. If not, the meta information will have to
1389 be recreated later, and may be incorrect.
1390
1391 If you provide a method object, this method will clone that object if
1392 the object's package name does not match the class name. This lets us
1393 track the original source of any methods added from other classes
1394 (notably Moose roles).
1395
1396 =item B<< $metaclass->remove_method($method_name) >>
1397
1398 Remove the named method from the class. This method returns the
1399 L<Class::MOP::Method> object for the method.
1400
1401 =back
1402
1403 =head2 Attribute introspection and creation
1404
1405 Because Perl 5 does not have a core concept of attributes in classes,
1406 we can only return information about attributes which have been added
1407 via this class's methods. We cannot discover information about
1408 attributes which are defined in terms of "regular" Perl 5 methods.
1409
1410 =over 4
1411
1412 =item B<< $metaclass->get_attribute($attribute_name) >>
1413
1414 This will return a L<Class::MOP::Attribute> for the specified
1415 C<$attribute_name>. If the class does not have the specified
1416 attribute, it returns C<undef>
1417
1418 =item B<< $metaclass->has_attribute($attribute_name) >>
1419
1420 Returns a boolean indicating whether or not the class defines the
1421 named attribute. It does not include attributes inherited from parent
1422 classes.
1423
1424 =item B<< $metaclass->get_attribute_map >>
1425
1426 Returns a hash reference representing the attributes defined in this
1427 class. The keys are attribute names and the values are
1428 L<Class::MOP::Attribute> objects.
1429
1430 =item B<< $metaclass->get_attribute_list >>
1431
1432 This will return a list of attributes I<names> for all attributes
1433 defined in this class.
1434
1435 =item B<< $metaclass->get_all_attributes >>
1436
1437 This will traverse the inheritance hierarchy and return a list of all
1438 the L<Class::MOP::Attribute> objects for this class and its parents.
1439
1440 This method can also be called as C<compute_all_applicable_attributes>.
1441
1442 =item B<< $metaclass->find_attribute_by_name($attribute_name) >>
1443
1444 This will return a L<Class::MOP::Attribute> for the specified
1445 C<$attribute_name>. If the class does not have the specified
1446 attribute, it returns C<undef>
1447
1448 Unlike C<get_attribute>, this attribute I<will> look for the named
1449 attribute in superclasses.
1450
1451 =item B<< $metaclass->add_attribute(...) >>
1452
1453 This method accepts either an existing L<Class::MOP::Attribute>
1454 object, or parameters suitable for passing to that class's C<new>
1455 method.
1456
1457 The attribute provided will be added to the class.
1458
1459 Any accessor methods defined by the attribute will be added to the
1460 class when the attribute is added.
1461
1462 If an attribute of the same name already exists, the old attribute
1463 will be removed first.
1464
1465 =item B<< $metaclass->remove_attribute($attribute_name) >>
1466
1467 This will remove the named attribute from the class, and
1468 L<Class::MOP::Attribute> object.
1469
1470 Removing an attribute also removes any accessor methods defined by the
1471 attribute.
1472
1473 However, note that removing an attribute will only affect I<future>
1474 object instances created for this class, not existing instances.
1475
1476 =item B<< $metaclass->attribute_metaclass >>
1477
1478 Returns the class name of the attribute metaclass for this class. By
1479 default, this is L<Class::MOP::Attribute>.  for more information on
1480
1481 =back
1482
1483 =head2 Class Immutability
1484
1485 Making a class immutable "freezes" the class definition. You can no
1486 longer call methods which alter the class, such as adding or removing
1487 methods or attributes.
1488
1489 Making a class immutable lets us optimize the class by inlining some
1490 methods, and also allows us to optimize some methods on the metaclass
1491 object itself.
1492
1493 The immutabilization system in L<Moose> takes much greater advantage
1494 of the inlining features than Class::MOP itself does.
1495
1496 =over 4
1497
1498 =item B<< $metaclass->make_immutable(%options) >>
1499
1500 This method will create an immutable transformer and uses it to make
1501 the class and its metaclass object immutable.
1502
1503 Details of how immutabilization works are in L<Class::MOP::Immutable>
1504 documentation.
1505
1506 =item B<< $metaclass->make_mutable >>
1507
1508 Calling this method reverse the immutabilization transformation.
1509
1510 =item B<< $metaclass->immutable_transformer >>
1511
1512 If the class has been made immutable previously, this returns the
1513 L<Class::MOP::Immutable> object that was created to do the
1514 transformation.
1515
1516 If the class was never made immutable, this method will die.
1517
1518 =back
1519
1520 =head2 Method Modifiers
1521
1522 Method modifiers are hooks which allow a method to be wrapped with
1523 I<before>, I<after> and I<around> method modifiers. Every time a
1524 method is called, it's modifiers are also called.
1525
1526 A class can modify its own methods, as well as methods defined in
1527 parent classes.
1528
1529 =head3 How method modifiers work?
1530
1531 Method modifiers work by wrapping the original method and then
1532 replacing it in the class's symbol table. The wrappers will handle
1533 calling all the modifiers in the appropriate order and preserving the
1534 calling context for the original method.
1535
1536 The return values of C<before> and C<after> modifiers are
1537 ignored. This is because their purpose is B<not> to filter the input
1538 and output of the primary method (this is done with an I<around>
1539 modifier).
1540
1541 This may seem like an odd restriction to some, but doing this allows
1542 for simple code to be added at the beginning or end of a method call
1543 without altering the function of the wrapped method or placing any
1544 extra responsibility on the code of the modifier.
1545
1546 Of course if you have more complex needs, you can use the C<around>
1547 modifier which allows you to change both the parameters passed to the
1548 wrapped method, as well as its return value.
1549
1550 Before and around modifiers are called in last-defined-first-called
1551 order, while after modifiers are called in first-defined-first-called
1552 order. So the call tree might looks something like this:
1553
1554   before 2
1555    before 1
1556     around 2
1557      around 1
1558       primary
1559      around 1
1560     around 2
1561    after 1
1562   after 2
1563
1564 =head3 What is the performance impact?
1565
1566 Of course there is a performance cost associated with method
1567 modifiers, but we have made every effort to make that cost directly
1568 proportional to the number of modifier features you utilize.
1569
1570 The wrapping method does it's best to B<only> do as much work as it
1571 absolutely needs to. In order to do this we have moved some of the
1572 performance costs to set-up time, where they are easier to amortize.
1573
1574 All this said, our benchmarks have indicated the following:
1575
1576   simple wrapper with no modifiers             100% slower
1577   simple wrapper with simple before modifier   400% slower
1578   simple wrapper with simple after modifier    450% slower
1579   simple wrapper with simple around modifier   500-550% slower
1580   simple wrapper with all 3 modifiers          1100% slower
1581
1582 These numbers may seem daunting, but you must remember, every feature
1583 comes with some cost. To put things in perspective, just doing a
1584 simple C<AUTOLOAD> which does nothing but extract the name of the
1585 method called and return it costs about 400% over a normal method
1586 call.
1587
1588 =over 4
1589
1590 =item B<< $metaclass->add_before_method_modifier($method_name, $code) >>
1591
1592 This wraps the specified method with the supplied subroutine
1593 reference. The modifier will be called as a method itself, and will
1594 receive the same arguments as are passed to the method.
1595
1596 When the modifier exits, the wrapped method will be called.
1597
1598 The return value of the modifier will be ignored.
1599
1600 =item B<< $metaclass->add_after_method_modifier($method_name, $code) >>
1601
1602 This wraps the specified method with the supplied subroutine
1603 reference. The modifier will be called as a method itself, and will
1604 receive the same arguments as are passed to the method.
1605
1606 When the wrapped methods exits, the modifier will be called.
1607
1608 The return value of the modifier will be ignored.
1609
1610 =item B<< $metaclass->add_around_method_modifier($method_name, $code) >>
1611
1612 This wraps the specified method with the supplied subroutine
1613 reference.
1614
1615 The first argument passed to the modifier will be a subroutine
1616 reference to the wrapped method. The second argument is the object,
1617 and after that come any arguments passed when the method is called.
1618
1619 The around modifier can choose to call the original method, as well as
1620 what arguments to pass if it does so.
1621
1622 The return value of the modifier is what will be seen by the caller.
1623
1624 =back
1625
1626 =head2 Introspection
1627
1628 =over 4
1629
1630 =item B<< Class::MOP::Class->meta >>
1631
1632 This will return a L<Class::MOP::Class> instance for this class.
1633
1634 It should also be noted that L<Class::MOP> will actually bootstrap
1635 this module by installing a number of attribute meta-objects into its
1636 metaclass.
1637
1638 =back
1639
1640 =head1 AUTHORS
1641
1642 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1643
1644 =head1 COPYRIGHT AND LICENSE
1645
1646 Copyright 2006-2009 by Infinity Interactive, Inc.
1647
1648 L<http://www.iinteractive.com>
1649
1650 This library is free software; you can redistribute it and/or modify
1651 it under the same terms as Perl itself.
1652
1653 =cut