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