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