foo-bar
[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
6c9f390e 16our $VERSION = '0.25';
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
6c9f390e 1091=item B<subclasses>
1092
1093This returns a list of subclasses for this class.
1094
552e3d24 1095=back
1096
1097=head2 Methods
1098
1099=over 4
1100
c4260b45 1101=item B<get_method_map>
1102
2e41896e 1103=item B<method_metaclass>
1104
552e3d24 1105=item B<add_method ($method_name, $method)>
1106
0ac992ee 1107This will take a C<$method_name> and CODE reference to that
1108C<$method> and install it into the class's package.
552e3d24 1109
0ac992ee 1110B<NOTE>:
1111This does absolutely nothing special to C<$method>
1112other than use B<Sub::Name> to make sure it is tagged with the
1113correct name, and therefore show up correctly in stack traces and
552e3d24 1114such.
1115
663f8198 1116=item B<alias_method ($method_name, $method)>
1117
0ac992ee 1118This will take a C<$method_name> and CODE reference to that
1119C<$method> and alias the method into the class's package.
663f8198 1120
0ac992ee 1121B<NOTE>:
1122Unlike C<add_method>, this will B<not> try to name the
1123C<$method> using B<Sub::Name>, it only aliases the method in
1124the class's package.
663f8198 1125
552e3d24 1126=item B<has_method ($method_name)>
1127
0ac992ee 1128This just provides a simple way to check if the class implements
1129a specific C<$method_name>. It will I<not> however, attempt to check
a2e85e6c 1130if the class inherits the method (use C<UNIVERSAL::can> for that).
552e3d24 1131
0ac992ee 1132This will correctly handle functions defined outside of the package
552e3d24 1133that use a fully qualified name (C<sub Package::name { ... }>).
1134
0ac992ee 1135This will correctly handle functions renamed with B<Sub::Name> and
1136installed using the symbol tables. However, if you are naming the
1137subroutine outside of the package scope, you must use the fully
1138qualified name, including the package name, for C<has_method> to
1139correctly identify it.
552e3d24 1140
0ac992ee 1141This will attempt to correctly ignore functions imported from other
1142packages using B<Exporter>. It breaks down if the function imported
1143is an C<__ANON__> sub (such as with C<use constant>), which very well
1144may be a valid method being applied to the class.
552e3d24 1145
0ac992ee 1146In short, this method cannot always be trusted to determine if the
1147C<$method_name> is actually a method. However, it will DWIM about
a2e85e6c 114890% of the time, so it's a small trade off I think.
552e3d24 1149
1150=item B<get_method ($method_name)>
1151
0ac992ee 1152This will return a Class::MOP::Method instance related to the specified
86482605 1153C<$method_name>, or return undef if that method does not exist.
1154
0ac992ee 1155The Class::MOP::Method is codifiable, so you can use it like a normal
86482605 1156CODE reference, see L<Class::MOP::Method> for more information.
552e3d24 1157
16e960bd 1158=item B<find_method_by_name ($method_name>
1159
1160This will return a CODE reference of the specified C<$method_name>,
1161or return undef if that method does not exist.
1162
1163Unlike C<get_method> this will also look in the superclasses.
1164
552e3d24 1165=item B<remove_method ($method_name)>
1166
0ac992ee 1167This will attempt to remove a given C<$method_name> from the class.
1168It will return the CODE reference that it has removed, and will
552e3d24 1169attempt to use B<Sub::Name> to clear the methods associated name.
1170
1171=item B<get_method_list>
1172
0ac992ee 1173This will return a list of method names for all I<locally> defined
1174methods. It does B<not> provide a list of all applicable methods,
1175including any inherited ones. If you want a list of all applicable
552e3d24 1176methods, use the C<compute_all_applicable_methods> method.
1177
1178=item B<compute_all_applicable_methods>
1179
0ac992ee 1180This will return a list of all the methods names this class will
1181respond to, taking into account inheritance. The list will be a list of
1182HASH references, each one containing the following information; method
1183name, the name of the class in which the method lives and a CODE
552e3d24 1184reference for the actual method.
1185
1186=item B<find_all_methods_by_name ($method_name)>
1187
0ac992ee 1188This will traverse the inheritence hierarchy and locate all methods
1189with a given C<$method_name>. Similar to
1190C<compute_all_applicable_methods> it returns a list of HASH references
1191with the following information; method name (which will always be the
1192same as C<$method_name>), the name of the class in which the method
552e3d24 1193lives and a CODE reference for the actual method.
1194
0ac992ee 1195The list of methods produced is a distinct list, meaning there are no
1196duplicates in it. This is especially useful for things like object
1197initialization and destruction where you only want the method called
552e3d24 1198once, and in the correct order.
1199
96ceced8 1200=item B<find_next_method_by_name ($method_name)>
1201
0ac992ee 1202This will return the first method to match a given C<$method_name> in
1203the superclasses, this is basically equivalent to calling
96ceced8 1204C<SUPER::$method_name>, but it can be dispatched at runtime.
1205
552e3d24 1206=back
1207
a4258ffd 1208=head2 Method Modifiers
1209
0ac992ee 1210Method modifiers are a concept borrowed from CLOS, in which a method
1211can be wrapped with I<before>, I<after> and I<around> method modifiers
1212that will be called everytime the method is called.
96ceced8 1213
1214=head3 How method modifiers work?
1215
0ac992ee 1216Method modifiers work by wrapping the original method and then replacing
1217it in the classes symbol table. The wrappers will handle calling all the
1218modifiers in the appropariate orders and preserving the calling context
1219for the original method.
1220
1221Each method modifier serves a particular purpose, which may not be
1222obvious to users of other method wrapping modules. To start with, the
1223return values of I<before> and I<after> modifiers are ignored. This is
1224because thier purpose is B<not> to filter the input and output of the
1225primary method (this is done with an I<around> modifier). This may seem
1226like an odd restriction to some, but doing this allows for simple code
1227to be added at the begining or end of a method call without jeapordizing
1228the normal functioning of the primary method or placing any extra
1229responsibility on the code of the modifier. Of course if you have more
1230complex needs, then use the I<around> modifier, which uses a variation
1231of continutation passing style to allow for a high degree of flexibility.
1232
1233Before and around modifiers are called in last-defined-first-called order,
1234while after modifiers are called in first-defined-first-called order. So
96ceced8 1235the call tree might looks something like this:
0ac992ee 1236
96ceced8 1237 before 2
1238 before 1
1239 around 2
1240 around 1
1241 primary
1242 after 1
1243 after 2
1244
0ac992ee 1245To see examples of using method modifiers, see the following examples
1246included in the distribution; F<InstanceCountingClass>, F<Perl6Attribute>,
1247F<AttributesWithHistory> and F<C3MethodDispatchOrder>. There is also a
96ceced8 1248classic CLOS usage example in the test F<017_add_method_modifier.t>.
1249
1250=head3 What is the performance impact?
1251
0ac992ee 1252Of course there is a performance cost associated with method modifiers,
1253but we have made every effort to make that cost be directly proportional
96ceced8 1254to the amount of modifier features you utilize.
1255
0ac992ee 1256The wrapping method does it's best to B<only> do as much work as it
1257absolutely needs to. In order to do this we have moved some of the
96ceced8 1258performance costs to set-up time, where they are easier to amortize.
1259
1260All this said, my benchmarks have indicated the following:
1261
1262 simple wrapper with no modifiers 100% slower
1263 simple wrapper with simple before modifier 400% slower
1264 simple wrapper with simple after modifier 450% slower
1265 simple wrapper with simple around modifier 500-550% slower
1266 simple wrapper with all 3 modifiers 1100% slower
1267
0ac992ee 1268These numbers may seem daunting, but you must remember, every feature
1269comes with some cost. To put things in perspective, just doing a simple
96ceced8 1270C<AUTOLOAD> which does nothing but extract the name of the method called
0ac992ee 1271and return it costs about 400% over a normal method call.
96ceced8 1272
a4258ffd 1273=over 4
1274
1275=item B<add_before_method_modifier ($method_name, $code)>
1276
0ac992ee 1277This will wrap the method at C<$method_name> and the supplied C<$code>
1278will be passed the C<@_> arguments, and called before the original
1279method is called. As specified above, the return value of the I<before>
1280method modifiers is ignored, and it's ability to modify C<@_> is
1281fairly limited. If you need to do either of these things, use an
96ceced8 1282C<around> method modifier.
1283
a4258ffd 1284=item B<add_after_method_modifier ($method_name, $code)>
1285
0ac992ee 1286This will wrap the method at C<$method_name> so that the original
1287method will be called, it's return values stashed, and then the
96ceced8 1288supplied C<$code> will be passed the C<@_> arguments, and called.
0ac992ee 1289As specified above, the return value of the I<after> method
1290modifiers is ignored, and it cannot modify the return values of
1291the original method. If you need to do either of these things, use an
96ceced8 1292C<around> method modifier.
1293
a4258ffd 1294=item B<add_around_method_modifier ($method_name, $code)>
1295
0ac992ee 1296This will wrap the method at C<$method_name> so that C<$code>
1297will be called and passed the original method as an extra argument
1298at the begining of the C<@_> argument list. This is a variation of
1299continuation passing style, where the function prepended to C<@_>
1300can be considered a continuation. It is up to C<$code> if it calls
1301the original method or not, there is no restriction on what the
96ceced8 1302C<$code> can or cannot do.
1303
a4258ffd 1304=back
1305
552e3d24 1306=head2 Attributes
1307
0ac992ee 1308It should be noted that since there is no one consistent way to define
1309the attributes of a class in Perl 5. These methods can only work with
1310the information given, and can not easily discover information on
a2e85e6c 1311their own. See L<Class::MOP::Attribute> for more details.
552e3d24 1312
1313=over 4
1314
2e41896e 1315=item B<attribute_metaclass>
1316
7b31baf4 1317=item B<get_attribute_map>
1318
8203616d 1319=item B<add_attribute ($attribute_meta_object | $attribute_name, %attribute_spec)>
552e3d24 1320
8203616d 1321This stores the C<$attribute_meta_object> (or creates one from the
0ac992ee 1322C<$attribute_name> and C<%attribute_spec>) in the B<Class::MOP::Class>
1323instance associated with the given class. Unlike methods, attributes
1324within the MOP are stored as meta-information only. They will be used
8203616d 1325later to construct instances from (see C<construct_instance> above).
0ac992ee 1326More details about the attribute meta-objects can be found in the
a2e85e6c 1327L<Class::MOP::Attribute> or the L<Class::MOP/The Attribute protocol>
1328section.
1329
0ac992ee 1330It should be noted that any accessor, reader/writer or predicate
1331methods which the C<$attribute_meta_object> has will be installed
a2e85e6c 1332into the class at this time.
552e3d24 1333
86482605 1334B<NOTE>
0ac992ee 1335If an attribute already exists for C<$attribute_name>, the old one
1336will be removed (as well as removing all it's accessors), and then
86482605 1337the new one added.
1338
552e3d24 1339=item B<has_attribute ($attribute_name)>
1340
0ac992ee 1341Checks to see if this class has an attribute by the name of
552e3d24 1342C<$attribute_name> and returns a boolean.
1343
1344=item B<get_attribute ($attribute_name)>
1345
0ac992ee 1346Returns the attribute meta-object associated with C<$attribute_name>,
1347if none is found, it will return undef.
552e3d24 1348
1349=item B<remove_attribute ($attribute_name)>
1350
0ac992ee 1351This will remove the attribute meta-object stored at
1352C<$attribute_name>, then return the removed attribute meta-object.
552e3d24 1353
0ac992ee 1354B<NOTE:>
1355Removing an attribute will only affect future instances of
1356the class, it will not make any attempt to remove the attribute from
552e3d24 1357any existing instances of the class.
1358
0ac992ee 1359It should be noted that any accessor, reader/writer or predicate
1360methods which the attribute meta-object stored at C<$attribute_name>
1361has will be removed from the class at this time. This B<will> make
1362these attributes somewhat inaccessable in previously created
1363instances. But if you are crazy enough to do this at runtime, then
a2e85e6c 1364you are crazy enough to deal with something like this :).
1365
552e3d24 1366=item B<get_attribute_list>
1367
0ac992ee 1368This returns a list of attribute names which are defined in the local
1369class. If you want a list of all applicable attributes for a class,
552e3d24 1370use the C<compute_all_applicable_attributes> method.
1371
1372=item B<compute_all_applicable_attributes>
1373
0ac992ee 1374This will traverse the inheritance heirachy and return a list of all
1375the applicable attributes for this class. It does not construct a
1376HASH reference like C<compute_all_applicable_methods> because all
1377that same information is discoverable through the attribute
c9e77dbb 1378meta-object itself.
552e3d24 1379
058c1cf5 1380=item B<find_attribute_by_name ($attr_name)>
1381
0ac992ee 1382This method will traverse the inheritance heirachy and find the
1383first attribute whose name matches C<$attr_name>, then return it.
058c1cf5 1384It will return undef if nothing is found.
1385
552e3d24 1386=back
1387
96e38ba6 1388=head2 Class Immutability
857f87a7 1389
1390=over 4
1391
96e38ba6 1392=item B<make_immutable (%options)>
1393
0ac992ee 1394This method will invoke a tranforamtion upon the class which will
1395make it immutable. Details of this transformation can be found in
96e38ba6 1396the L<Class::MOP::Immutable> documentation.
857f87a7 1397
0ac992ee 1398=item B<make_mutable>
1399
1400This method will reverse tranforamtion upon the class which
1401made it immutable.
1402
b817e248 1403=item B<create_immutable_transformer>
1404
1405Create a transformer suitable for making this class immutable
1406
857f87a7 1407=back
1408
1a09d9cc 1409=head1 AUTHORS
8b978dd5 1410
a2e85e6c 1411Stevan Little E<lt>stevan@iinteractive.comE<gt>
8b978dd5 1412
1413=head1 COPYRIGHT AND LICENSE
1414
2367814a 1415Copyright 2006, 2007 by Infinity Interactive, Inc.
8b978dd5 1416
1417L<http://www.iinteractive.com>
1418
1419This library is free software; you can redistribute it and/or modify
0ac992ee 1420it under the same terms as Perl itself.
8b978dd5 1421
798baea5 1422=cut