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