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