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