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