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