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