2 package Class::MOP::Class;
7 use Class::MOP::Immutable;
8 use Class::MOP::Instance;
9 use Class::MOP::Method::Wrapped;
12 use Scalar::Util 'blessed', 'weaken';
14 our $VERSION = '0.76';
15 $VERSION = eval $VERSION;
16 our $AUTHORITY = 'cpan:STEVAN';
18 use base 'Class::MOP::Module';
28 $package_name = shift;
31 $package_name = $options{package};
34 (defined $package_name && $package_name && !ref($package_name))
35 || confess "You must pass a package name and it cannot be blessed";
37 return Class::MOP::get_metaclass_by_name($package_name)
38 || $class->construct_class_instance(package => $package_name, @_);
41 # NOTE: (meta-circularity)
42 # this is a special form of &construct_instance
43 # (see below), which is used to construct class
44 # meta-object instances for any Class::MOP::*
45 # class. All other classes will use the more
46 # normal &construct_instance.
47 sub construct_class_instance {
49 my $options = @_ == 1 ? $_[0] : {@_};
50 my $package_name = $options->{package};
51 (defined $package_name && $package_name)
52 || confess "You must pass a package name";
54 # return the metaclass if we have it cached,
55 # and it is still defined (it has not been
56 # reaped by DESTROY yet, which can happen
57 # annoyingly enough during global destruction)
59 if (defined(my $meta = Class::MOP::get_metaclass_by_name($package_name))) {
64 # we need to deal with the possibility
65 # of class immutability here, and then
66 # get the name of the class appropriately
68 ? ($class->is_immutable
69 ? $class->get_mutable_metaclass_name()
73 # now create the metaclass
75 if ($class eq 'Class::MOP::Class') {
77 $meta = $class->_new($options)
81 # it is safe to use meta here because
82 # class will always be a subclass of
83 # Class::MOP::Class, which defines meta
84 $meta = $class->meta->construct_instance($options)
87 # and check the metaclass compatibility
88 $meta->check_metaclass_compatibility();
90 Class::MOP::store_metaclass_by_name($package_name, $meta);
93 # we need to weaken any anon classes
94 # so that they can call DESTROY properly
95 Class::MOP::weaken_metaclass($package_name) if $meta->is_anon_class;
102 my $options = @_ == 1 ? $_[0] : {@_};
105 # inherited from Class::MOP::Package
106 'package' => $options->{package},
109 # since the following attributes will
110 # actually be loaded from the symbol
111 # table, and actually bypass the instance
112 # entirely, we can just leave these things
113 # listed here for reference, because they
114 # should not actually have a value associated
116 'namespace' => \undef,
118 # inherited from Class::MOP::Module
120 'authority' => \undef,
122 # defined in Class::MOP::Class
123 'superclasses' => \undef,
127 'attribute_metaclass' => $options->{'attribute_metaclass'}
128 || 'Class::MOP::Attribute',
129 'method_metaclass' => $options->{'method_metaclass'}
130 || 'Class::MOP::Method',
131 'wrapped_method_metaclass' => $options->{'wrapped_method_metaclass'}
132 || 'Class::MOP::Method::Wrapped',
133 'instance_metaclass' => $options->{'instance_metaclass'}
134 || 'Class::MOP::Instance',
138 sub reset_package_cache_flag { (shift)->{'_package_cache_flag'} = undef }
139 sub update_package_cache_flag {
142 # we can manually update the cache number
143 # since we are actually adding the method
144 # to our cache as well. This avoids us
145 # having to regenerate the method_map.
147 $self->{'_package_cache_flag'} = Class::MOP::check_package_cache_flag($self->name);
150 sub check_metaclass_compatibility {
153 # this is always okay ...
154 return if ref($self) eq 'Class::MOP::Class' &&
155 $self->instance_metaclass eq 'Class::MOP::Instance';
157 my @class_list = $self->linearized_isa;
158 shift @class_list; # shift off $self->name
160 foreach my $class_name (@class_list) {
161 my $meta = Class::MOP::get_metaclass_by_name($class_name) || next;
164 # we need to deal with the possibility
165 # of class immutability here, and then
166 # get the name of the class appropriately
167 my $meta_type = ($meta->is_immutable
168 ? $meta->get_mutable_metaclass_name()
171 ($self->isa($meta_type))
172 || confess $self->name . "->meta => (" . (ref($self)) . ")" .
173 " is not compatible with the " .
174 $class_name . "->meta => (" . ($meta_type) . ")";
176 # we also need to check that instance metaclasses
177 # are compatibile in the same the class.
178 ($self->instance_metaclass->isa($meta->instance_metaclass))
179 || confess $self->name . "->meta->instance_metaclass => (" . ($self->instance_metaclass) . ")" .
180 " is not compatible with the " .
181 $class_name . "->meta->instance_metaclass => (" . ($meta->instance_metaclass) . ")";
185 # backwards compat for stevan's inability to spell ;)
186 sub check_metaclass_compatability {
188 $self->check_metaclass_compatibility(@_);
195 # this should be sufficient, if you have a
196 # use case where it is not, write a test and
198 my $ANON_CLASS_SERIAL = 0;
201 # we need a sufficiently annoying prefix
202 # this should suffice for now, this is
203 # used in a couple of places below, so
204 # need to put it up here for now.
205 my $ANON_CLASS_PREFIX = 'Class::MOP::Class::__ANON__::SERIAL::';
209 no warnings 'uninitialized';
210 $self->name =~ /^$ANON_CLASS_PREFIX/;
213 sub create_anon_class {
214 my ($class, %options) = @_;
215 my $package_name = $ANON_CLASS_PREFIX . ++$ANON_CLASS_SERIAL;
216 return $class->create($package_name, %options);
220 # this will only get called for
221 # anon-classes, all other calls
222 # are assumed to occur during
223 # global destruction and so don't
224 # really need to be handled explicitly
228 return if Class::MOP::in_global_destruction(); # it'll happen soon anyway and this just makes things more complicated
230 no warnings 'uninitialized';
231 return unless $self->name =~ /^$ANON_CLASS_PREFIX/;
232 # Moose does a weird thing where it replaces the metaclass for
233 # class when fixing metaclass incompatibility. In that case,
234 # we don't want to clean out the namespace now. We can detect
235 # that because Moose will explicitly update the singleton
236 # cache in Class::MOP.
237 my $current_meta = Class::MOP::get_metaclass_by_name($self->name);
238 return if $current_meta ne $self;
240 my ($serial_id) = ($self->name =~ /^$ANON_CLASS_PREFIX(\d+)/);
242 foreach my $key (keys %{$ANON_CLASS_PREFIX . $serial_id}) {
243 delete ${$ANON_CLASS_PREFIX . $serial_id}{$key};
245 delete ${'main::' . $ANON_CLASS_PREFIX}{$serial_id . '::'};
250 # creating classes with MOP ...
253 my ( $class, @args ) = @_;
255 unshift @args, 'package' if @args % 2 == 1;
257 my (%options) = @args;
258 my $package_name = $options{package};
260 (ref $options{superclasses} eq 'ARRAY')
261 || confess "You must pass an ARRAY ref of superclasses"
262 if exists $options{superclasses};
264 (ref $options{attributes} eq 'ARRAY')
265 || confess "You must pass an ARRAY ref of attributes"
266 if exists $options{attributes};
268 (ref $options{methods} eq 'HASH')
269 || confess "You must pass a HASH ref of methods"
270 if exists $options{methods};
272 $class->SUPER::create(%options);
274 my (%initialize_options) = @args;
275 delete @initialize_options{qw(
283 my $meta = $class->initialize( $package_name => %initialize_options );
286 $meta->add_method('meta' => sub {
287 $class->initialize(ref($_[0]) || $_[0]);
290 $meta->superclasses(@{$options{superclasses}})
291 if exists $options{superclasses};
293 # process attributes first, so that they can
294 # install accessors, but locally defined methods
295 # can then overwrite them. It is maybe a little odd, but
296 # I think this should be the order of things.
297 if (exists $options{attributes}) {
298 foreach my $attr (@{$options{attributes}}) {
299 $meta->add_attribute($attr);
302 if (exists $options{methods}) {
303 foreach my $method_name (keys %{$options{methods}}) {
304 $meta->add_method($method_name, $options{methods}->{$method_name});
313 # all these attribute readers will be bootstrapped
314 # away in the Class::MOP bootstrap section
316 sub get_attribute_map { $_[0]->{'attributes'} }
317 sub attribute_metaclass { $_[0]->{'attribute_metaclass'} }
318 sub method_metaclass { $_[0]->{'method_metaclass'} }
319 sub wrapped_method_metaclass { $_[0]->{'wrapped_method_metaclass'} }
320 sub instance_metaclass { $_[0]->{'instance_metaclass'} }
325 my $class_name = $self->name;
327 my $current = Class::MOP::check_package_cache_flag($class_name);
329 if (defined $self->{'_package_cache_flag'} && $self->{'_package_cache_flag'} == $current) {
330 return $self->{'methods'} ||= {};
333 $self->{_package_cache_flag} = $current;
335 my $map = $self->{'methods'} ||= {};
337 my $method_metaclass = $self->method_metaclass;
339 my $all_code = $self->get_all_package_symbols('CODE');
341 foreach my $symbol (keys %{ $all_code }) {
342 my $code = $all_code->{$symbol};
344 next if exists $map->{$symbol} &&
345 defined $map->{$symbol} &&
346 $map->{$symbol}->body == $code;
348 my ($pkg, $name) = Class::MOP::get_code_info($code);
351 # in 5.10 constant.pm the constants show up
352 # as being in the right package, but in pre-5.10
353 # they show up as constant::__ANON__ so we
354 # make an exception here to be sure that things
355 # work as expected in both.
357 unless ($pkg eq 'constant' && $name eq '__ANON__') {
358 next if ($pkg || '') ne $class_name ||
359 (($name || '') ne '__ANON__' && ($pkg || '') ne $class_name);
362 $map->{$symbol} = $method_metaclass->wrap(
364 associated_metaclass => $self,
365 package_name => $class_name,
373 # Instance Construction & Cloning
379 # we need to protect the integrity of the
380 # Class::MOP::Class singletons here, so we
381 # delegate this to &construct_class_instance
382 # which will deal with the singletons
383 return $class->construct_class_instance(@_)
384 if $class->name->isa('Class::MOP::Class');
385 return $class->construct_instance(@_);
388 sub construct_instance {
390 my $params = @_ == 1 ? $_[0] : {@_};
391 my $meta_instance = $class->get_meta_instance();
392 my $instance = $meta_instance->create_instance();
393 foreach my $attr ($class->compute_all_applicable_attributes()) {
394 $attr->initialize_instance_slot($meta_instance, $instance, $params);
397 # this will only work for a HASH instance type
398 if ($class->is_anon_class) {
399 (Scalar::Util::reftype($instance) eq 'HASH')
400 || confess "Currently only HASH based instances are supported with instance of anon-classes";
402 # At some point we should make this official
403 # as a reserved slot name, but right now I am
404 # going to keep it here.
405 # my $RESERVED_MOP_SLOT = '__MOP__';
406 $instance->{'__MOP__'} = $class;
412 sub get_meta_instance {
414 $self->{'_meta_instance'} ||= $self->create_meta_instance();
417 sub create_meta_instance {
420 my $instance = $self->instance_metaclass->new(
421 associated_metaclass => $self,
422 attributes => [ $self->compute_all_applicable_attributes() ],
425 $self->add_meta_instance_dependencies()
426 if $instance->is_dependent_on_superclasses();
433 my $instance = shift;
434 (blessed($instance) && $instance->isa($class->name))
435 || confess "You must pass an instance of the metaclass (" . (ref $class ? $class->name : $class) . "), not ($instance)";
438 # we need to protect the integrity of the
439 # Class::MOP::Class singletons here, they
440 # should not be cloned.
441 return $instance if $instance->isa('Class::MOP::Class');
442 $class->clone_instance($instance, @_);
446 my ($class, $instance, %params) = @_;
448 || confess "You can only clone instances, ($instance) is not a blessed instance";
449 my $meta_instance = $class->get_meta_instance();
450 my $clone = $meta_instance->clone_instance($instance);
451 foreach my $attr ($class->compute_all_applicable_attributes()) {
452 if ( defined( my $init_arg = $attr->init_arg ) ) {
453 if (exists $params{$init_arg}) {
454 $attr->set_value($clone, $params{$init_arg});
461 sub rebless_instance {
462 my ($self, $instance, %params) = @_;
465 if ($instance->can('meta')) {
466 ($instance->meta->isa('Class::MOP::Class'))
467 || confess 'Cannot rebless instance if ->meta is not an instance of Class::MOP::Class';
468 $old_metaclass = $instance->meta;
471 $old_metaclass = $self->initialize(ref($instance));
474 my $meta_instance = $self->get_meta_instance();
476 $self->name->isa($old_metaclass->name)
477 || confess "You may rebless only into a subclass of (". $old_metaclass->name ."), of which (". $self->name .") isn't.";
480 $meta_instance->rebless_instance_structure($instance, $self);
482 foreach my $attr ( $self->compute_all_applicable_attributes ) {
483 if ( $attr->has_value($instance) ) {
484 if ( defined( my $init_arg = $attr->init_arg ) ) {
485 $params{$init_arg} = $attr->get_value($instance)
486 unless exists $params{$init_arg};
489 $attr->set_value($instance, $attr->get_value($instance));
494 foreach my $attr ($self->compute_all_applicable_attributes) {
495 $attr->initialize_instance_slot($meta_instance, $instance, \%params);
505 my $var_spec = { sigil => '@', type => 'ARRAY', name => 'ISA' };
508 @{$self->get_package_symbol($var_spec)} = @supers;
511 # on 5.8 and below, we need to call
512 # a method to get Perl to detect
513 # a cycle in the class hierarchy
514 my $class = $self->name;
518 # we need to check the metaclass
519 # compatibility here so that we can
520 # be sure that the superclass is
521 # not potentially creating an issues
522 # we don't know about
524 $self->check_metaclass_compatibility();
525 $self->update_meta_instance_dependencies();
527 @{$self->get_package_symbol($var_spec)};
533 my $super_class = $self->name;
535 if ( Class::MOP::HAVE_ISAREV() ) {
536 return @{ $super_class->mro::get_isarev() };
540 my $find_derived_classes;
541 $find_derived_classes = sub {
542 my ($outer_class) = @_;
544 my $symbol_table_hashref = do { no strict 'refs'; \%{"${outer_class}::"} };
547 for my $symbol ( keys %$symbol_table_hashref ) {
548 next SYMBOL if $symbol !~ /\A (\w+):: \z/x;
549 my $inner_class = $1;
551 next SYMBOL if $inner_class eq 'SUPER'; # skip '*::SUPER'
555 ? "${outer_class}::$inner_class"
558 if ( $class->isa($super_class) and $class ne $super_class ) {
559 push @derived_classes, $class;
562 next SYMBOL if $class eq 'main'; # skip 'main::*'
564 $find_derived_classes->($class);
568 my $root_class = q{};
569 $find_derived_classes->($root_class);
571 undef $find_derived_classes;
573 @derived_classes = sort { $a->isa($b) ? 1 : $b->isa($a) ? -1 : 0 } @derived_classes;
575 return @derived_classes;
581 return @{ mro::get_linear_isa( (shift)->name ) };
584 sub class_precedence_list {
586 my $name = $self->name;
588 unless (Class::MOP::IS_RUNNING_ON_5_10()) {
590 # We need to check for circular inheritance here
591 # if we are are not on 5.10, cause 5.8 detects it
592 # late. This will do nothing if all is well, and
593 # blow up otherwise. Yes, it's an ugly hack, better
594 # suggestions are welcome.
596 ($name || return)->isa('This is a test for circular inheritance')
599 # if our mro is c3, we can
600 # just grab the linear_isa
601 if (mro::get_mro($name) eq 'c3') {
602 return @{ mro::get_linear_isa($name) }
606 # we can't grab the linear_isa for dfs
607 # since it has all the duplicates
612 $self->initialize($_)->class_precedence_list()
613 } $self->superclasses()
620 sub wrap_method_body {
621 my ( $self, %args ) = @_;
623 ('CODE' eq ref $args{body})
624 || confess "Your code block must be a CODE reference";
626 $self->method_metaclass->wrap(
627 package_name => $self->name,
633 my ($self, $method_name, $method) = @_;
634 (defined $method_name && $method_name)
635 || confess "You must define a method name";
638 if (blessed($method)) {
639 $body = $method->body;
640 if ($method->package_name ne $self->name) {
641 $method = $method->clone(
642 package_name => $self->name,
644 ) if $method->can('clone');
649 $method = $self->wrap_method_body( body => $body, name => $method_name );
652 $method->attach_to_class($self);
654 # This used to call get_method_map, which meant we would build all
655 # the method objects for the class just because we added one
656 # method. This is hackier, but quicker too.
657 $self->{methods}{$method_name} = $method;
659 my $full_method_name = ($self->name . '::' . $method_name);
660 $self->add_package_symbol(
661 { sigil => '&', type => 'CODE', name => $method_name },
662 Class::MOP::subname($full_method_name => $body)
667 my $fetch_and_prepare_method = sub {
668 my ($self, $method_name) = @_;
669 my $wrapped_metaclass = $self->wrapped_method_metaclass;
671 my $method = $self->get_method($method_name);
672 # if we dont have local ...
674 # try to find the next method
675 $method = $self->find_next_method_by_name($method_name);
676 # die if it does not exist
678 || confess "The method '$method_name' is not found in the inheritance hierarchy for class " . $self->name;
679 # and now make sure to wrap it
680 # even if it is already wrapped
681 # because we need a new sub ref
682 $method = $wrapped_metaclass->wrap($method);
685 # now make sure we wrap it properly
686 $method = $wrapped_metaclass->wrap($method)
687 unless $method->isa($wrapped_metaclass);
689 $self->add_method($method_name => $method);
693 sub add_before_method_modifier {
694 my ($self, $method_name, $method_modifier) = @_;
695 (defined $method_name && $method_name)
696 || confess "You must pass in a method name";
697 my $method = $fetch_and_prepare_method->($self, $method_name);
698 $method->add_before_modifier(
699 Class::MOP::subname(':before' => $method_modifier)
703 sub add_after_method_modifier {
704 my ($self, $method_name, $method_modifier) = @_;
705 (defined $method_name && $method_name)
706 || confess "You must pass in a method name";
707 my $method = $fetch_and_prepare_method->($self, $method_name);
708 $method->add_after_modifier(
709 Class::MOP::subname(':after' => $method_modifier)
713 sub add_around_method_modifier {
714 my ($self, $method_name, $method_modifier) = @_;
715 (defined $method_name && $method_name)
716 || confess "You must pass in a method name";
717 my $method = $fetch_and_prepare_method->($self, $method_name);
718 $method->add_around_modifier(
719 Class::MOP::subname(':around' => $method_modifier)
724 # the methods above used to be named like this:
725 # ${pkg}::${method}:(before|after|around)
726 # but this proved problematic when using one modifier
727 # to wrap multiple methods (something which is likely
728 # to happen pretty regularly IMO). So instead of naming
729 # it like this, I have chosen to just name them purely
730 # with their modifier names, like so:
731 # :(before|after|around)
732 # The fact is that in a stack trace, it will be fairly
733 # evident from the context what method they are attached
734 # to, and so don't need the fully qualified name.
740 $self->add_method(@_);
744 my ($self, $method_name) = @_;
745 (defined $method_name && $method_name)
746 || confess "You must define a method name";
748 exists $self->{methods}{$method_name} || exists $self->get_method_map->{$method_name};
752 my ($self, $method_name) = @_;
753 (defined $method_name && $method_name)
754 || confess "You must define a method name";
756 return $self->{methods}{$method_name} || $self->get_method_map->{$method_name};
760 my ($self, $method_name) = @_;
761 (defined $method_name && $method_name)
762 || confess "You must define a method name";
764 my $removed_method = delete $self->get_method_map->{$method_name};
766 $self->remove_package_symbol(
767 { sigil => '&', type => 'CODE', name => $method_name }
770 $removed_method->detach_from_class if $removed_method;
772 $self->update_package_cache_flag; # still valid, since we just removed the method from the map
774 return $removed_method;
777 sub get_method_list {
779 keys %{$self->get_method_map};
782 sub find_method_by_name {
783 my ($self, $method_name) = @_;
784 (defined $method_name && $method_name)
785 || confess "You must define a method name to find";
786 foreach my $class ($self->linearized_isa) {
787 # fetch the meta-class ...
788 my $meta = $self->initialize($class);
789 return $meta->get_method($method_name)
790 if $meta->has_method($method_name);
795 sub get_all_methods {
797 my %methods = map { %{ $self->initialize($_)->get_method_map } } reverse $self->linearized_isa;
798 return values %methods;
802 sub compute_all_applicable_methods {
806 class => $_->package_name,
807 code => $_, # sigh, overloading
809 } shift->get_all_methods(@_);
812 sub get_all_method_names {
815 grep { $uniq{$_}++ == 0 } map { $_->name } $self->get_all_methods;
818 sub find_all_methods_by_name {
819 my ($self, $method_name) = @_;
820 (defined $method_name && $method_name)
821 || confess "You must define a method name to find";
823 foreach my $class ($self->linearized_isa) {
824 # fetch the meta-class ...
825 my $meta = $self->initialize($class);
827 name => $method_name,
829 code => $meta->get_method($method_name)
830 } if $meta->has_method($method_name);
835 sub find_next_method_by_name {
836 my ($self, $method_name) = @_;
837 (defined $method_name && $method_name)
838 || confess "You must define a method name to find";
839 my @cpl = $self->linearized_isa;
840 shift @cpl; # discard ourselves
841 foreach my $class (@cpl) {
842 # fetch the meta-class ...
843 my $meta = $self->initialize($class);
844 return $meta->get_method($method_name)
845 if $meta->has_method($method_name);
854 # either we have an attribute object already
855 # or we need to create one from the args provided
856 my $attribute = blessed($_[0]) ? $_[0] : $self->attribute_metaclass->new(@_);
857 # make sure it is derived from the correct type though
858 ($attribute->isa('Class::MOP::Attribute'))
859 || confess "Your attribute must be an instance of Class::MOP::Attribute (or a subclass)";
861 # first we attach our new attribute
862 # because it might need certain information
863 # about the class which it is attached to
864 $attribute->attach_to_class($self);
866 # then we remove attributes of a conflicting
867 # name here so that we can properly detach
868 # the old attr object, and remove any
869 # accessors it would have generated
870 if ( $self->has_attribute($attribute->name) ) {
871 $self->remove_attribute($attribute->name);
873 $self->invalidate_meta_instances();
876 # then onto installing the new accessors
877 $self->get_attribute_map->{$attribute->name} = $attribute;
879 # invalidate package flag here
880 my $e = do { local $@; eval { $attribute->install_accessors() }; $@ };
882 $self->remove_attribute($attribute->name);
889 sub update_meta_instance_dependencies {
892 if ( $self->{meta_instance_dependencies} ) {
893 return $self->add_meta_instance_dependencies;
897 sub add_meta_instance_dependencies {
900 $self->remove_meta_instance_depdendencies;
902 my @attrs = $self->compute_all_applicable_attributes();
905 my @classes = grep { not $seen{$_->name}++ } map { $_->associated_class } @attrs;
907 foreach my $class ( @classes ) {
908 $class->add_dependent_meta_instance($self);
911 $self->{meta_instance_dependencies} = \@classes;
914 sub remove_meta_instance_depdendencies {
917 if ( my $classes = delete $self->{meta_instance_dependencies} ) {
918 foreach my $class ( @$classes ) {
919 $class->remove_dependent_meta_instance($self);
929 sub add_dependent_meta_instance {
930 my ( $self, $metaclass ) = @_;
931 push @{ $self->{dependent_meta_instances} }, $metaclass;
934 sub remove_dependent_meta_instance {
935 my ( $self, $metaclass ) = @_;
936 my $name = $metaclass->name;
937 @$_ = grep { $_->name ne $name } @$_ for $self->{dependent_meta_instances};
940 sub invalidate_meta_instances {
942 $_->invalidate_meta_instance() for $self, @{ $self->{dependent_meta_instances} };
945 sub invalidate_meta_instance {
947 undef $self->{_meta_instance};
951 my ($self, $attribute_name) = @_;
952 (defined $attribute_name && $attribute_name)
953 || confess "You must define an attribute name";
954 exists $self->get_attribute_map->{$attribute_name};
958 my ($self, $attribute_name) = @_;
959 (defined $attribute_name && $attribute_name)
960 || confess "You must define an attribute name";
961 return $self->get_attribute_map->{$attribute_name}
963 # this will return undef anyway, so no need ...
964 # if $self->has_attribute($attribute_name);
968 sub remove_attribute {
969 my ($self, $attribute_name) = @_;
970 (defined $attribute_name && $attribute_name)
971 || confess "You must define an attribute name";
972 my $removed_attribute = $self->get_attribute_map->{$attribute_name};
973 return unless defined $removed_attribute;
974 delete $self->get_attribute_map->{$attribute_name};
975 $self->invalidate_meta_instances();
976 $removed_attribute->remove_accessors();
977 $removed_attribute->detach_from_class();
978 return $removed_attribute;
981 sub get_attribute_list {
983 keys %{$self->get_attribute_map};
986 sub get_all_attributes {
987 shift->compute_all_applicable_attributes(@_);
990 sub compute_all_applicable_attributes {
992 my %attrs = map { %{ $self->initialize($_)->get_attribute_map } } reverse $self->linearized_isa;
993 return values %attrs;
996 sub find_attribute_by_name {
997 my ($self, $attr_name) = @_;
998 foreach my $class ($self->linearized_isa) {
999 # fetch the meta-class ...
1000 my $meta = $self->initialize($class);
1001 return $meta->get_attribute($attr_name)
1002 if $meta->has_attribute($attr_name);
1007 # check if we can reinitialize
1011 # if any local attr is defined
1012 return if $self->get_attribute_list;
1014 # or any non-declared methods
1015 if ( my @methods = values %{ $self->get_method_map } ) {
1016 my $metaclass = $self->method_metaclass;
1017 foreach my $method ( @methods ) {
1018 return if $method->isa("Class::MOP::Method::Generated");
1019 # FIXME do we need to enforce this too? return unless $method->isa($metaclass);
1028 sub is_mutable { 1 }
1029 sub is_immutable { 0 }
1032 # Why I changed this (groditi)
1033 # - One Metaclass may have many Classes through many Metaclass instances
1034 # - One Metaclass should only have one Immutable Transformer instance
1035 # - Each Class may have different Immutabilizing options
1036 # - Therefore each Metaclass instance may have different Immutabilizing options
1037 # - We need to store one Immutable Transformer instance per Metaclass
1038 # - We need to store one set of Immutable Transformer options per Class
1039 # - Upon make_mutable we may delete the Immutabilizing options
1040 # - We could clean the immutable Transformer instance when there is no more
1041 # immutable Classes of that type, but we can also keep it in case
1042 # another class with this same Metaclass becomes immutable. It is a case
1043 # of trading of storing an instance to avoid unnecessary instantiations of
1044 # Immutable Transformers. You may view this as a memory leak, however
1045 # Because we have few Metaclasses, in practice it seems acceptable
1046 # - To allow Immutable Transformers instances to be cleaned up we could weaken
1047 # the reference stored in $IMMUTABLE_TRANSFORMERS{$class} and ||= should DWIM
1051 my %IMMUTABLE_TRANSFORMERS;
1052 my %IMMUTABLE_OPTIONS;
1054 sub get_immutable_options {
1056 return if $self->is_mutable;
1057 confess "unable to find immutabilizing options"
1058 unless exists $IMMUTABLE_OPTIONS{$self->name};
1059 my %options = %{$IMMUTABLE_OPTIONS{$self->name}};
1060 delete $options{IMMUTABLE_TRANSFORMER};
1064 sub get_immutable_transformer {
1066 if( $self->is_mutable ){
1067 return $IMMUTABLE_TRANSFORMERS{$self->name} ||= $self->create_immutable_transformer;
1069 confess "unable to find transformer for immutable class"
1070 unless exists $IMMUTABLE_OPTIONS{$self->name};
1071 return $IMMUTABLE_OPTIONS{$self->name}->{IMMUTABLE_TRANSFORMER};
1074 sub make_immutable {
1078 my $transformer = $self->get_immutable_transformer;
1079 $transformer->make_metaclass_immutable($self, \%options);
1080 $IMMUTABLE_OPTIONS{$self->name} =
1081 { %options, IMMUTABLE_TRANSFORMER => $transformer };
1083 if( exists $options{debug} && $options{debug} ){
1084 print STDERR "# of Metaclass options: ", keys %IMMUTABLE_OPTIONS;
1085 print STDERR "# of Immutable transformers: ", keys %IMMUTABLE_TRANSFORMERS;
1093 return if $self->is_mutable;
1094 my $options = delete $IMMUTABLE_OPTIONS{$self->name};
1095 confess "unable to find immutabilizing options" unless ref $options;
1096 my $transformer = delete $options->{IMMUTABLE_TRANSFORMER};
1097 $transformer->make_metaclass_mutable($self, $options);
1102 sub create_immutable_transformer {
1104 my $class = Class::MOP::Immutable->new($self, {
1105 read_only => [qw/superclasses/],
1112 remove_package_symbol
1115 class_precedence_list => 'ARRAY',
1116 linearized_isa => 'ARRAY', # FIXME perl 5.10 memoizes this on its own, no need?
1117 get_all_methods => 'ARRAY',
1118 get_all_method_names => 'ARRAY',
1119 #get_all_attributes => 'ARRAY', # it's an alias, no need, but maybe in the future
1120 compute_all_applicable_attributes => 'ARRAY',
1121 get_meta_instance => 'SCALAR',
1122 get_method_map => 'SCALAR',
1125 # this is ugly, but so are typeglobs,
1126 # so whattayahgonnadoboutit
1129 add_package_symbol => sub {
1130 my $original = shift;
1131 confess "Cannot add package symbols to an immutable metaclass"
1132 unless (caller(2))[3] eq 'Class::MOP::Package::get_package_symbol';
1134 # This is a workaround for a bug in 5.8.1 which thinks that
1135 # goto $original->body
1136 # is trying to go to a label
1137 my $body = $original->body;
1153 Class::MOP::Class - Class Meta Object
1157 # assuming that class Foo
1158 # has been defined, you can
1160 # use this for introspection ...
1162 # add a method to Foo ...
1163 Foo->meta->add_method('bar' => sub { ... })
1165 # get a list of all the classes searched
1166 # the method dispatcher in the correct order
1167 Foo->meta->class_precedence_list()
1169 # remove a method from Foo
1170 Foo->meta->remove_method('bar');
1172 # or use this to actually create classes ...
1174 Class::MOP::Class->create('Bar' => (
1176 superclasses => [ 'Foo' ],
1178 Class::MOP:::Attribute->new('$bar'),
1179 Class::MOP:::Attribute->new('$baz'),
1182 calculate_bar => sub { ... },
1183 construct_baz => sub { ... }
1189 This is the largest and currently most complex part of the Perl 5
1190 meta-object protocol. It controls the introspection and
1191 manipulation of Perl 5 classes (and it can create them too). The
1192 best way to understand what this module can do, is to read the
1193 documentation for each of it's methods.
1197 B<Class::MOP::Class> is a subclass of L<Class::MOP::Module>
1201 =head2 Self Introspection
1207 This will return a B<Class::MOP::Class> instance which is related
1208 to this class. Thereby allowing B<Class::MOP::Class> to actually
1211 As with B<Class::MOP::Attribute>, B<Class::MOP> will actually
1212 bootstrap this module by installing a number of attribute meta-objects
1213 into it's metaclass. This will allow this class to reap all the benifits
1214 of the MOP when subclassing it.
1218 =head2 Class construction
1220 These methods will handle creating B<Class::MOP::Class> objects,
1221 which can be used to both create new classes, and analyze
1222 pre-existing classes.
1224 This module will internally store references to all the instances
1225 you create with these methods, so that they do not need to be
1226 created any more than nessecary. Basically, they are singletons.
1230 =item B<create ($package_name,
1231 version =E<gt> ?$version,
1232 authority =E<gt> ?$authority,
1233 superclasses =E<gt> ?@superclasses,
1234 methods =E<gt> ?%methods,
1235 attributes =E<gt> ?%attributes)>
1237 This returns a B<Class::MOP::Class> object, bringing the specified
1238 C<$package_name> into existence and adding any of the C<$version>,
1239 C<$authority>, C<@superclasses>, C<%methods> and C<%attributes> to
1242 =item B<create_anon_class (superclasses =E<gt> ?@superclasses,
1243 methods =E<gt> ?%methods,
1244 attributes =E<gt> ?%attributes)>
1246 This will create an anonymous class, it works much like C<create> but
1247 it does not need a C<$package_name>. Instead it will create a suitably
1248 unique package name for you to stash things into.
1250 On very important distinction is that anon classes are destroyed once
1251 the metaclass they are attached to goes out of scope. In the DESTROY
1252 method, the created package will be removed from the symbol table.
1254 It is also worth noting that any instances created with an anon-class
1255 will keep a special reference to the anon-meta which will prevent the
1256 anon-class from going out of scope until all instances of it have also
1257 been destroyed. This however only works for HASH based instance types,
1258 as we use a special reserved slot (C<__MOP__>) to store this.
1260 =item B<initialize ($package_name, %options)>
1262 This initializes and returns returns a B<Class::MOP::Class> object for
1263 a given a C<$package_name>. If a metaclass already exists for the
1264 package, it simply returns it instead of creating a new one.
1266 =item B<construct_class_instance (%options)>
1268 This will construct an instance of B<Class::MOP::Class>, it is
1269 here so that we can actually "tie the knot" for B<Class::MOP::Class>
1270 to use C<construct_instance> once all the bootstrapping is done. This
1271 method is used internally by C<initialize> and should never be called
1272 from outside of that method really.
1274 =item B<check_metaclass_compatibility>
1276 This method is called as the very last thing in the
1277 C<construct_class_instance> method. This will check that the
1278 metaclass you are creating is compatible with the metaclasses of all
1279 your ancestors. For more inforamtion about metaclass compatibility
1280 see the C<About Metaclass compatibility> section in L<Class::MOP>.
1282 =item B<update_package_cache_flag>
1284 This will reset the package cache flag for this particular metaclass
1285 it is basically the value of the C<Class::MOP::get_package_cache_flag>
1286 function. This is very rarely needed from outside of C<Class::MOP::Class>
1287 but in some cases you might want to use it, so it is here.
1289 =item B<reset_package_cache_flag>
1291 Clears the package cache flag to announce to the internals that we need
1292 to rebuild the method map.
1294 =item B<add_meta_instance_dependencies>
1296 Registers this class as dependent on its superclasses.
1298 Only superclasses from which this class inherits attributes will be added.
1300 =item B<remove_meta_instance_depdendencies>
1302 Unregisters this class from its superclasses.
1304 =item B<update_meta_instance_dependencies>
1306 Reregisters if necessary.
1308 =item B<add_dependent_meta_instance> $metaclass
1310 Registers the class as having a meta instance dependent on this class.
1312 =item B<remove_dependent_meta_instance> $metaclass
1314 Remove the class from the list of dependent classes.
1316 =item B<invalidate_meta_instances>
1318 Clears the cached meta instance for this metaclass and all of the registered
1319 classes with dependent meta instances.
1321 Called by C<add_attribute> and C<remove_attribute> to recalculate the attribute
1324 =item B<invalidate_meta_instance>
1326 Used by C<invalidate_meta_instances>.
1330 =head2 Object instance construction and cloning
1332 These methods are B<entirely optional>, it is up to you whether you want
1337 =item B<instance_metaclass>
1339 Returns the class name of the instance metaclass, see L<Class::MOP::Instance>
1340 for more information on the instance metaclasses.
1342 =item B<get_meta_instance>
1344 Returns an instance of L<Class::MOP::Instance> to be used in the construction
1345 of a new instance of the class.
1347 =item B<create_meta_instance>
1349 Called by C<get_meta_instance> if necessary.
1351 =item B<new_object (%params)>
1353 This is a convience method for creating a new object of the class, and
1354 blessing it into the appropriate package as well. Ideally your class
1355 would call a C<new> this method like so:
1358 my ($class, %param) = @_;
1359 $class->meta->new_object(%params);
1362 =item B<construct_instance (%params)>
1364 This method is used to construct an instance structure suitable for
1365 C<bless>-ing into your package of choice. It works in conjunction
1366 with the Attribute protocol to collect all applicable attributes.
1368 This will construct an instance using a HASH ref as storage
1369 (currently only HASH references are supported). This will collect all
1370 the applicable attributes and layout out the fields in the HASH ref,
1371 it will then initialize them using either use the corresponding key
1372 in C<%params> or any default value or initializer found in the
1373 attribute meta-object.
1375 =item B<clone_object ($instance, %params)>
1377 This is a convience method for cloning an object instance, then
1378 blessing it into the appropriate package. This method will call
1379 C<clone_instance>, which performs a shallow copy of the object,
1380 see that methods documentation for more details. Ideally your
1381 class would call a C<clone> this method like so:
1383 sub MyClass::clone {
1384 my ($self, %param) = @_;
1385 $self->meta->clone_object($self, %params);
1388 =item B<clone_instance($instance, %params)>
1390 This method is a compliment of C<construct_instance> (which means if
1391 you override C<construct_instance>, you need to override this one too),
1392 and clones the instance shallowly.
1394 The cloned structure returned is (like with C<construct_instance>) an
1395 unC<bless>ed HASH reference, it is your responsibility to then bless
1396 this cloned structure into the right class (which C<clone_object> will
1399 As of 0.11, this method will clone the C<$instance> structure shallowly,
1400 as opposed to the deep cloning implemented in prior versions. After much
1401 thought, research and discussion, I have decided that anything but basic
1402 shallow cloning is outside the scope of the meta-object protocol. I
1403 think Yuval "nothingmuch" Kogman put it best when he said that cloning
1404 is too I<context-specific> to be part of the MOP.
1406 =item B<rebless_instance($instance, ?%params)>
1408 This will change the class of C<$instance> to the class of the invoking
1409 C<Class::MOP::Class>. You may only rebless the instance to a subclass of
1410 itself. You may pass in optional C<%params> which are like constructor
1411 params and will override anything already defined in the instance.
1415 =head2 Informational
1417 These are a few predicate methods for asking information about the class.
1421 =item B<is_anon_class>
1423 This returns true if the class is a C<Class::MOP::Class> created anon class.
1427 This returns true if the class is still mutable.
1429 =item B<is_immutable>
1431 This returns true if the class has been made immutable.
1433 =item B<is_pristine>
1435 Checks whether the class has any data that will be lost if C<reinitialize> is
1440 =head2 Inheritance Relationships
1444 =item B<superclasses (?@superclasses)>
1446 This is a read-write attribute which represents the superclass
1447 relationships of the class the B<Class::MOP::Class> instance is
1448 associated with. Basically, it can get and set the C<@ISA> for you.
1450 =item B<class_precedence_list>
1452 This computes the a list of all the class's ancestors in the same order
1453 in which method dispatch will be done. This is similair to what
1454 B<Class::ISA::super_path> does, but we don't remove duplicate names.
1456 =item B<linearized_isa>
1458 This returns a list based on C<class_precedence_list> but with all
1463 This returns a list of subclasses for this class.
1471 =item B<get_method_map>
1473 Returns a HASH ref of name to L<Class::MOP::Method> instance mapping
1476 =item B<method_metaclass>
1478 Returns the class name of the method metaclass, see L<Class::MOP::Method>
1479 for more information on the method metaclasses.
1481 =item B<wrap_method_body(%attrs)>
1483 Wrap a code ref (C<$attrs{body>) with C<method_metaclass>.
1485 =item B<add_method ($method_name, $method)>
1487 This will take a C<$method_name> and CODE reference or meta method
1488 objectand install it into the class's package.
1490 You are strongly encouraged to pass a meta method object instead of a
1491 code reference. If you do so, that object gets stored as part of the
1492 class's method map, providing more useful information about the method
1495 When you provide a method object, this method will clone that object
1496 if the object's package name does not match the class name. This lets
1497 us track the original source of any methods added from other classes
1498 (notably Moose roles).
1501 This does absolutely nothing special to C<$method>
1502 other than use B<Sub::Name> to make sure it is tagged with the
1503 correct name, and therefore show up correctly in stack traces and
1506 =item B<has_method ($method_name)>
1508 This just provides a simple way to check if the class implements
1509 a specific C<$method_name>. It will I<not> however, attempt to check
1510 if the class inherits the method (use C<UNIVERSAL::can> for that).
1512 This will correctly handle functions defined outside of the package
1513 that use a fully qualified name (C<sub Package::name { ... }>).
1515 This will correctly handle functions renamed with B<Sub::Name> and
1516 installed using the symbol tables. However, if you are naming the
1517 subroutine outside of the package scope, you must use the fully
1518 qualified name, including the package name, for C<has_method> to
1519 correctly identify it.
1521 This will attempt to correctly ignore functions imported from other
1522 packages using B<Exporter>. It breaks down if the function imported
1523 is an C<__ANON__> sub (such as with C<use constant>), which very well
1524 may be a valid method being applied to the class.
1526 In short, this method cannot always be trusted to determine if the
1527 C<$method_name> is actually a method. However, it will DWIM about
1528 90% of the time, so it's a small trade off I think.
1530 =item B<get_method ($method_name)>
1532 This will return a Class::MOP::Method instance related to the specified
1533 C<$method_name>, or return undef if that method does not exist.
1535 The Class::MOP::Method is codifiable, so you can use it like a normal
1536 CODE reference, see L<Class::MOP::Method> for more information.
1538 =item B<find_method_by_name ($method_name)>
1540 This will return a L<Class::MOP::Method> instance for the specified
1541 C<$method_name>, or return undef if that method does not exist.
1543 Unlike C<get_method> this will also look in the superclasses.
1545 =item B<remove_method ($method_name)>
1547 This will attempt to remove a given C<$method_name> from the class.
1548 It will return the L<Class::MOP::Method> instance that it has removed,
1549 and will attempt to use B<Sub::Name> to clear the methods associated
1552 =item B<get_method_list>
1554 This will return a list of method names for all I<locally> defined
1555 methods. It does B<not> provide a list of all applicable methods,
1556 including any inherited ones. If you want a list of all applicable
1557 methods, use the C<compute_all_applicable_methods> method.
1559 =item B<get_all_methods>
1561 This will traverse the inheritance heirachy and return a list of all
1562 the applicable L<Class::MOP::Method> objects for this class.
1564 =item B<compute_all_applicable_methods>
1568 This method returns a list of hashes describing the all the methods of the
1571 Use L<get_all_methods>, which is easier/better/faster. This method predates
1572 L<Class::MOP::Method>.
1574 =item B<get_all_method_names>
1576 This will traverse the inheritance heirachy and return a list of all the
1577 applicable method names for this class. Duplicate names are removed, but the
1578 order the methods come out is not defined.
1580 =item B<find_all_methods_by_name ($method_name)>
1582 This will traverse the inheritence hierarchy and locate all methods
1583 with a given C<$method_name>. Similar to
1584 C<compute_all_applicable_methods> it returns a list of HASH references
1585 with the following information; method name (which will always be the
1586 same as C<$method_name>), the name of the class in which the method
1587 lives and a CODE reference for the actual method.
1589 The list of methods produced is a distinct list, meaning there are no
1590 duplicates in it. This is especially useful for things like object
1591 initialization and destruction where you only want the method called
1592 once, and in the correct order.
1594 =item B<find_next_method_by_name ($method_name)>
1596 This will return the first method to match a given C<$method_name> in
1597 the superclasses, this is basically equivalent to calling
1598 C<SUPER::$method_name>, but it can be dispatched at runtime.
1600 =item B<alias_method ($method_name, $method)>
1602 B<NOTE>: This method is now deprecated. Just use C<add_method>
1607 =head2 Method Modifiers
1609 Method modifiers are a concept borrowed from CLOS, in which a method
1610 can be wrapped with I<before>, I<after> and I<around> method modifiers
1611 that will be called everytime the method is called.
1613 =head3 How method modifiers work?
1615 Method modifiers work by wrapping the original method and then replacing
1616 it in the classes symbol table. The wrappers will handle calling all the
1617 modifiers in the appropariate orders and preserving the calling context
1618 for the original method.
1620 Each method modifier serves a particular purpose, which may not be
1621 obvious to users of other method wrapping modules. To start with, the
1622 return values of I<before> and I<after> modifiers are ignored. This is
1623 because thier purpose is B<not> to filter the input and output of the
1624 primary method (this is done with an I<around> modifier). This may seem
1625 like an odd restriction to some, but doing this allows for simple code
1626 to be added at the begining or end of a method call without jeapordizing
1627 the normal functioning of the primary method or placing any extra
1628 responsibility on the code of the modifier. Of course if you have more
1629 complex needs, then use the I<around> modifier, which uses a variation
1630 of continutation passing style to allow for a high degree of flexibility.
1632 Before and around modifiers are called in last-defined-first-called order,
1633 while after modifiers are called in first-defined-first-called order. So
1634 the call tree might looks something like this:
1646 To see examples of using method modifiers, see the following examples
1647 included in the distribution; F<InstanceCountingClass>, F<Perl6Attribute>,
1648 F<AttributesWithHistory> and F<C3MethodDispatchOrder>. There is also a
1649 classic CLOS usage example in the test F<017_add_method_modifier.t>.
1651 =head3 What is the performance impact?
1653 Of course there is a performance cost associated with method modifiers,
1654 but we have made every effort to make that cost be directly proportional
1655 to the amount of modifier features you utilize.
1657 The wrapping method does it's best to B<only> do as much work as it
1658 absolutely needs to. In order to do this we have moved some of the
1659 performance costs to set-up time, where they are easier to amortize.
1661 All this said, my benchmarks have indicated the following:
1663 simple wrapper with no modifiers 100% slower
1664 simple wrapper with simple before modifier 400% slower
1665 simple wrapper with simple after modifier 450% slower
1666 simple wrapper with simple around modifier 500-550% slower
1667 simple wrapper with all 3 modifiers 1100% slower
1669 These numbers may seem daunting, but you must remember, every feature
1670 comes with some cost. To put things in perspective, just doing a simple
1671 C<AUTOLOAD> which does nothing but extract the name of the method called
1672 and return it costs about 400% over a normal method call.
1676 =item B<add_before_method_modifier ($method_name, $code)>
1678 This will wrap the method at C<$method_name> and the supplied C<$code>
1679 will be passed the C<@_> arguments, and called before the original
1680 method is called. As specified above, the return value of the I<before>
1681 method modifiers is ignored, and it's ability to modify C<@_> is
1682 fairly limited. If you need to do either of these things, use an
1683 C<around> method modifier.
1685 =item B<add_after_method_modifier ($method_name, $code)>
1687 This will wrap the method at C<$method_name> so that the original
1688 method will be called, it's return values stashed, and then the
1689 supplied C<$code> will be passed the C<@_> arguments, and called.
1690 As specified above, the return value of the I<after> method
1691 modifiers is ignored, and it cannot modify the return values of
1692 the original method. If you need to do either of these things, use an
1693 C<around> method modifier.
1695 =item B<add_around_method_modifier ($method_name, $code)>
1697 This will wrap the method at C<$method_name> so that C<$code>
1698 will be called and passed the original method as an extra argument
1699 at the begining of the C<@_> argument list. This is a variation of
1700 continuation passing style, where the function prepended to C<@_>
1701 can be considered a continuation. It is up to C<$code> if it calls
1702 the original method or not, there is no restriction on what the
1703 C<$code> can or cannot do.
1709 It should be noted that since there is no one consistent way to define
1710 the attributes of a class in Perl 5. These methods can only work with
1711 the information given, and can not easily discover information on
1712 their own. See L<Class::MOP::Attribute> for more details.
1716 =item B<attribute_metaclass>
1718 Returns the class name of the attribute metaclass, see L<Class::MOP::Attribute>
1719 for more information on the attribute metaclasses.
1721 =item B<get_attribute_map>
1723 This returns a HASH ref of name to attribute meta-object mapping.
1725 =item B<add_attribute ($attribute_meta_object | ($attribute_name, %attribute_spec))>
1727 This stores the C<$attribute_meta_object> (or creates one from the
1728 C<$attribute_name> and C<%attribute_spec>) in the B<Class::MOP::Class>
1729 instance associated with the given class. Unlike methods, attributes
1730 within the MOP are stored as meta-information only. They will be used
1731 later to construct instances from (see C<construct_instance> above).
1732 More details about the attribute meta-objects can be found in the
1733 L<Class::MOP::Attribute> or the L<Class::MOP/The Attribute protocol>
1736 It should be noted that any accessor, reader/writer or predicate
1737 methods which the C<$attribute_meta_object> has will be installed
1738 into the class at this time.
1741 If an attribute already exists for C<$attribute_name>, the old one
1742 will be removed (as well as removing all it's accessors), and then
1745 =item B<has_attribute ($attribute_name)>
1747 Checks to see if this class has an attribute by the name of
1748 C<$attribute_name> and returns a boolean.
1750 =item B<get_attribute ($attribute_name)>
1752 Returns the attribute meta-object associated with C<$attribute_name>,
1753 if none is found, it will return undef.
1755 =item B<remove_attribute ($attribute_name)>
1757 This will remove the attribute meta-object stored at
1758 C<$attribute_name>, then return the removed attribute meta-object.
1761 Removing an attribute will only affect future instances of
1762 the class, it will not make any attempt to remove the attribute from
1763 any existing instances of the class.
1765 It should be noted that any accessor, reader/writer or predicate
1766 methods which the attribute meta-object stored at C<$attribute_name>
1767 has will be removed from the class at this time. This B<will> make
1768 these attributes somewhat inaccessable in previously created
1769 instances. But if you are crazy enough to do this at runtime, then
1770 you are crazy enough to deal with something like this :).
1772 =item B<get_attribute_list>
1774 This returns a list of attribute names which are defined in the local
1775 class. If you want a list of all applicable attributes for a class,
1776 use the C<compute_all_applicable_attributes> method.
1778 =item B<compute_all_applicable_attributes>
1780 =item B<get_all_attributes>
1782 This will traverse the inheritance heirachy and return a list of all
1783 the applicable L<Class::MOP::Attribute> objects for this class.
1785 C<get_all_attributes> is an alias for consistency with C<get_all_methods>.
1787 =item B<find_attribute_by_name ($attr_name)>
1789 This method will traverse the inheritance heirachy and find the
1790 first attribute whose name matches C<$attr_name>, then return it.
1791 It will return undef if nothing is found.
1795 =head2 Class Immutability
1799 =item B<make_immutable (%options)>
1801 This method will invoke a tranforamtion upon the class which will
1802 make it immutable. Details of this transformation can be found in
1803 the L<Class::MOP::Immutable> documentation.
1805 =item B<make_mutable>
1807 This method will reverse tranforamtion upon the class which
1810 =item B<get_immutable_transformer>
1812 Return a transformer suitable for making this class immutable or, if this
1813 class is immutable, the transformer used to make it immutable.
1815 =item B<get_immutable_options>
1817 If the class is immutable, return the options used to make it immutable.
1819 =item B<create_immutable_transformer>
1821 Create a transformer suitable for making this class immutable
1827 Stevan Little E<lt>stevan@iinteractive.comE<gt>
1829 =head1 COPYRIGHT AND LICENSE
1831 Copyright 2006-2008 by Infinity Interactive, Inc.
1833 L<http://www.iinteractive.com>
1835 This library is free software; you can redistribute it and/or modify
1836 it under the same terms as Perl itself.