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