Refactor this method to get rid of the indentation chain from hell.
[gitmo/Moose.git] / lib / Moose / Meta / Class.pm
CommitLineData
c0e30cf5 1
2package Moose::Meta::Class;
3
4use strict;
5use warnings;
6
0addec44 7use Class::MOP;
648e79ae 8
11c86f15 9use Carp ();
f8b6827f 10use List::Util qw( first );
8b1d510f 11use List::MoreUtils qw( any all uniq );
21f1e231 12use Scalar::Util 'weaken', 'blessed';
a15dff8d 13
e606ae5f 14our $VERSION = '0.57';
15$VERSION = eval $VERSION;
d44714be 16our $AUTHORITY = 'cpan:STEVAN';
bc1e29b5 17
8ee73eeb 18use Moose::Meta::Method::Overriden;
3f9e4b0a 19use Moose::Meta::Method::Augmented;
bf6fa6b3 20use Moose::Error::Default;
8ee73eeb 21
c0e30cf5 22use base 'Class::MOP::Class';
23
598340d5 24__PACKAGE__->meta->add_attribute('roles' => (
ef333f17 25 reader => 'roles',
26 default => sub { [] }
27));
28
e606ae5f 29__PACKAGE__->meta->add_attribute('constructor_class' => (
30 accessor => 'constructor_class',
e0001338 31 default => 'Moose::Meta::Method::Constructor',
e606ae5f 32));
33
34__PACKAGE__->meta->add_attribute('destructor_class' => (
35 accessor => 'destructor_class',
e0001338 36 default => 'Moose::Meta::Method::Destructor',
e606ae5f 37));
38
11c86f15 39__PACKAGE__->meta->add_attribute('error_class' => (
bf6fa6b3 40 accessor => 'error_class',
41 default => 'Moose::Error::Default',
11c86f15 42));
43
44
590868a3 45sub initialize {
46 my $class = shift;
47 my $pkg = shift;
685f7e44 48 return Class::MOP::get_metaclass_by_name($pkg)
49 || $class->SUPER::initialize($pkg,
50 'attribute_metaclass' => 'Moose::Meta::Attribute',
51 'method_metaclass' => 'Moose::Meta::Method',
52 'instance_metaclass' => 'Moose::Meta::Instance',
53 @_
54 );
ac2dc464 55}
590868a3 56
61bdd94f 57sub create {
58 my ($self, $package_name, %options) = @_;
59
60 (ref $options{roles} eq 'ARRAY')
11c86f15 61 || $self->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
61bdd94f 62 if exists $options{roles};
310ba883 63 my $roles = delete $options{roles};
dd37a5be 64
61bdd94f 65 my $class = $self->SUPER::create($package_name, %options);
dd37a5be 66
310ba883 67 if ($roles) {
68 Moose::Util::apply_all_roles( $class, @$roles );
61bdd94f 69 }
70
71 return $class;
72}
73
2b72f3b4 74sub check_metaclass_compatibility {
75 my $self = shift;
76
77 if ( my @supers = $self->superclasses ) {
78 $self->_fix_metaclass_incompatibility(@supers);
79 }
80
81 $self->SUPER::check_metaclass_compatibility(@_);
82}
83
17594769 84my %ANON_CLASSES;
85
86sub create_anon_class {
87 my ($self, %options) = @_;
88
89 my $cache_ok = delete $options{cache};
17594769 90
91 # something like Super::Class|Super::Class::2=Role|Role::1
92 my $cache_key = join '=' => (
6d5cbd2b 93 join('|', sort @{$options{superclasses} || []}),
94 join('|', sort @{$options{roles} || []}),
17594769 95 );
96
6d5cbd2b 97 if ($cache_ok && defined $ANON_CLASSES{$cache_key}) {
17594769 98 return $ANON_CLASSES{$cache_key};
99 }
100
101 my $new_class = $self->SUPER::create_anon_class(%options);
102
6d5cbd2b 103 $ANON_CLASSES{$cache_key} = $new_class
104 if $cache_ok;
17594769 105
106 return $new_class;
107}
108
ef333f17 109sub add_role {
110 my ($self, $role) = @_;
111 (blessed($role) && $role->isa('Moose::Meta::Role'))
11c86f15 112 || $self->throw_error("Roles must be instances of Moose::Meta::Role", data => $role);
ef333f17 113 push @{$self->roles} => $role;
114}
115
b8aeb4dc 116sub calculate_all_roles {
117 my $self = shift;
118 my %seen;
119 grep { !$seen{$_->name}++ } map { $_->calculate_all_roles } @{ $self->roles };
120}
121
ef333f17 122sub does_role {
123 my ($self, $role_name) = @_;
124 (defined $role_name)
11c86f15 125 || $self->throw_error("You must supply a role name to look for");
9c429218 126 foreach my $class ($self->class_precedence_list) {
81c3738f 127 next unless $class->can('meta') && $class->meta->can('roles');
9c429218 128 foreach my $role (@{$class->meta->roles}) {
129 return 1 if $role->does_role($role_name);
130 }
ef333f17 131 }
132 return 0;
133}
134
d79e62fd 135sub excludes_role {
136 my ($self, $role_name) = @_;
137 (defined $role_name)
11c86f15 138 || $self->throw_error("You must supply a role name to look for");
ac2dc464 139 foreach my $class ($self->class_precedence_list) {
140 next unless $class->can('meta');
5cb193ed 141 # NOTE:
142 # in the pretty rare instance when a Moose metaclass
ac2dc464 143 # is itself extended with a role, this check needs to
5cb193ed 144 # be done since some items in the class_precedence_list
ac2dc464 145 # might in fact be Class::MOP based still.
146 next unless $class->meta->can('roles');
9c429218 147 foreach my $role (@{$class->meta->roles}) {
148 return 1 if $role->excludes_role($role_name);
149 }
d79e62fd 150 }
151 return 0;
152}
153
8c9d74e7 154sub new_object {
1308deb4 155 my $class = shift;
e606ae5f 156 my $params = @_ == 1 ? $_[0] : {@_};
1308deb4 157 my $self = $class->SUPER::new_object($params);
158
159 foreach my $attr ( $class->compute_all_applicable_attributes() ) {
160
161 next unless $attr->can('has_trigger') && $attr->has_trigger;
162
163 my $init_arg = $attr->init_arg;
164
165 next unless defined $init_arg;
166
167 next unless exists $params->{$init_arg};
168
169 $attr->trigger->(
170 $self,
171 (
172 $attr->should_coerce
173 ? $attr->get_read_method_ref->($self)
174 : $params->{$init_arg}
175 ),
176 $attr
177 );
8c9d74e7 178 }
1308deb4 179
ac2dc464 180 return $self;
8c9d74e7 181}
182
a15dff8d 183sub construct_instance {
e606ae5f 184 my $class = shift;
185 my $params = @_ == 1 ? $_[0] : {@_};
ddd0ec20 186 my $meta_instance = $class->get_meta_instance;
575db57d 187 # FIXME:
188 # the code below is almost certainly incorrect
189 # but this is foreign inheritence, so we might
ac2dc464 190 # have to kludge it in the end.
e606ae5f 191 my $instance = $params->{'__INSTANCE__'} || $meta_instance->create_instance();
ac2dc464 192 foreach my $attr ($class->compute_all_applicable_attributes()) {
e606ae5f 193 $attr->initialize_instance_slot($meta_instance, $instance, $params);
a15dff8d 194 }
195 return $instance;
196}
197
093b12c2 198# FIXME:
199# This is ugly
ac2dc464 200sub get_method_map {
093b12c2 201 my $self = shift;
53dd42d8 202
e606ae5f 203 my $current = Class::MOP::check_package_cache_flag($self->name);
204
205 if (defined $self->{'_package_cache_flag'} && $self->{'_package_cache_flag'} == $current) {
206 return $self->{'methods'};
53dd42d8 207 }
208
e606ae5f 209 $self->{_package_cache_flag} = $current;
210
211 my $map = $self->{'methods'};
ac2dc464 212
093b12c2 213 my $class_name = $self->name;
214 my $method_metaclass = $self->method_metaclass;
ac2dc464 215
0addec44 216 my %all_code = $self->get_all_package_symbols('CODE');
ac2dc464 217
0addec44 218 foreach my $symbol (keys %all_code) {
219 my $code = $all_code{$symbol};
ac2dc464 220
221 next if exists $map->{$symbol} &&
222 defined $map->{$symbol} &&
223 $map->{$symbol}->body == $code;
224
53dd42d8 225 my ($pkg, $name) = Class::MOP::get_code_info($code);
ac2dc464 226
53dd42d8 227 if ($pkg->can('meta')
4f8f3aab 228 # NOTE:
229 # we don't know what ->meta we are calling
53dd42d8 230 # here, so we need to be careful cause it
231 # just might blow up at us, or just complain
232 # loudly (in the case of Curses.pm) so we
4f8f3aab 233 # just be a little overly cautious here.
234 # - SL
235 && eval { no warnings; blessed($pkg->meta) }
236 && $pkg->meta->isa('Moose::Meta::Role')) {
093b12c2 237 #my $role = $pkg->meta->name;
238 #next unless $self->does_role($role);
239 }
240 else {
2887c827 241
242 # NOTE:
243 # in 5.10 constant.pm the constants show up
244 # as being in the right package, but in pre-5.10
245 # they show up as constant::__ANON__ so we
246 # make an exception here to be sure that things
247 # work as expected in both.
248 # - SL
249 unless ($pkg eq 'constant' && $name eq '__ANON__') {
250 next if ($pkg || '') ne $class_name ||
251 (($name || '') ne '__ANON__' && ($pkg || '') ne $class_name);
252 }
53dd42d8 253
093b12c2 254 }
ac2dc464 255
1b2aea39 256 $map->{$symbol} = $method_metaclass->wrap(
257 $code,
258 package_name => $class_name,
259 name => $symbol
260 );
093b12c2 261 }
ac2dc464 262
093b12c2 263 return $map;
a7d0cd00 264}
265
093b12c2 266### ---------------------------------------------
267
a2eec5e7 268sub add_attribute {
269 my $self = shift;
e472c9a5 270 $self->SUPER::add_attribute(
271 (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
272 ? $_[0]
273 : $self->_process_attribute(@_))
274 );
a2eec5e7 275}
276
78cd1d3b 277sub add_override_method_modifier {
278 my ($self, $name, $method, $_super_package) = @_;
18c2ec0e 279
d05cd563 280 (!$self->has_method($name))
11c86f15 281 || $self->throw_error("Cannot add an override method if a local method is already present");
18c2ec0e 282
283 $self->add_method($name => Moose::Meta::Method::Overriden->new(
3f9e4b0a 284 method => $method,
285 class => $self,
286 package => $_super_package, # need this for roles
287 name => $name,
18c2ec0e 288 ));
78cd1d3b 289}
290
291sub add_augment_method_modifier {
ac2dc464 292 my ($self, $name, $method) = @_;
d05cd563 293 (!$self->has_method($name))
11c86f15 294 || $self->throw_error("Cannot add an augment method if a local method is already present");
3f9e4b0a 295
296 $self->add_method($name => Moose::Meta::Method::Augmented->new(
297 method => $method,
298 class => $self,
299 name => $name,
300 ));
78cd1d3b 301}
302
1341f10c 303## Private Utility methods ...
304
05d9eaf6 305sub _find_next_method_by_name_which_is_not_overridden {
306 my ($self, $name) = @_;
68efb014 307 foreach my $method ($self->find_all_methods_by_name($name)) {
ac2dc464 308 return $method->{code}
05d9eaf6 309 if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overriden');
310 }
311 return undef;
312}
313
41419b9e 314sub _fix_metaclass_incompatibility {
1341f10c 315 my ($self, @superclasses) = @_;
e606ae5f 316
1341f10c 317 foreach my $super (@superclasses) {
f8b6827f 318 next if $self->_superclass_meta_is_compatible($super);
e606ae5f 319
320 unless ( $self->is_pristine ) {
f8b6827f 321 $self->throw_error(
322 "Cannot attempt to reinitialize metaclass for "
323 . $self->name
324 . ", it isn't pristine" );
1341f10c 325 }
e606ae5f 326
0635500e 327 $self->_reconcile_with_superclass_meta($super);
f8b6827f 328 }
f8b6827f 329}
330
331sub _superclass_meta_is_compatible {
332 my ($self, $super) = @_;
333
334 my $super_meta = Class::MOP::Class->initialize($super)
335 or return 1;
336
337 next unless $super_meta->isa("Class::MOP::Class");
338
339 my $super_meta_name
340 = $super_meta->is_immutable
341 ? $super_meta->get_mutable_metaclass_name
342 : ref($super_meta);
343
344 return 1
345 if $self->isa($super_meta_name)
346 and
347 $self->instance_metaclass->isa( $super_meta->instance_metaclass );
348}
349
350# I don't want to have to type this >1 time
351my @MetaClassTypes =
8b1d510f 352 qw( attribute_metaclass method_metaclass instance_metaclass
353 constructor_class destructor_class error_class );
f8b6827f 354
355sub _reconcile_with_superclass_meta {
356 my ($self, $super) = @_;
357
358 my $super_meta = $super->meta;
359
dd37a5be 360 my $super_meta_name
f8b6827f 361 = $super_meta->is_immutable
362 ? $super_meta->get_mutable_metaclass_name
363 : ref($super_meta);
e606ae5f 364
f8b6827f 365 my $self_metaclass = ref $self;
366
367 # If neither of these is true we have a more serious
368 # incompatibility that we just cannot fix (yet?).
dd37a5be 369 if ( $super_meta_name->isa( ref $self )
f8b6827f 370 && all { $super_meta->$_->isa( $self->$_ ) } @MetaClassTypes ) {
0635500e 371 $self->_reinitialize_with($super_meta);
f8b6827f 372 }
373 elsif ( $self->_all_metaclasses_differ_by_roles_only($super_meta) ) {
0635500e 374 $self->_reconcile_role_differences($super_meta);
1341f10c 375 }
1341f10c 376}
377
f8b6827f 378sub _reinitialize_with {
379 my ( $self, $new_meta ) = @_;
380
0635500e 381 my $new_self = $new_meta->reinitialize(
f8b6827f 382 $self->name,
383 attribute_metaclass => $new_meta->attribute_metaclass,
384 method_metaclass => $new_meta->method_metaclass,
385 instance_metaclass => $new_meta->instance_metaclass,
386 );
387
8b1d510f 388 $new_self->$_( $new_meta->$_ )
389 for qw( constructor_class destructor_class error_class );
f8b6827f 390
0635500e 391 %$self = %$new_self;
392
393 bless $self, ref $new_self;
394
4c5fcc12 395 # We need to replace the cached metaclass instance or else when it
396 # goes out of scope Class::MOP::Class destroy's the namespace for
397 # the metaclass's class, causing much havoc.
0635500e 398 Class::MOP::store_metaclass_by_name( $self->name, $self );
4c5fcc12 399 Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class;
f8b6827f 400}
401
402# In the more complex case, we share a common ancestor with our
403# superclass's metaclass, but each metaclass (ours and the parent's)
404# has a different set of roles applied. We reconcile this by first
405# reinitializing into the parent class, and _then_ applying our own
406# roles.
407sub _all_metaclasses_differ_by_roles_only {
408 my ($self, $super_meta) = @_;
409
410 for my $pair (
411 [ ref $self, ref $super_meta ],
412 map { [ $self->$_, $super_meta->$_ ] } @MetaClassTypes
413 ) {
414
415 next if $pair->[0] eq $pair->[1];
416
417 my $self_meta_meta = Class::MOP::Class->initialize( $pair->[0] );
418 my $super_meta_meta = Class::MOP::Class->initialize( $pair->[1] );
419
420 my $common_ancestor
421 = _find_common_ancestor( $self_meta_meta, $super_meta_meta );
422
423 return unless $common_ancestor;
424
425 return
426 unless _is_role_only_subclass_of(
427 $self_meta_meta,
428 $common_ancestor,
429 )
430 && _is_role_only_subclass_of(
431 $super_meta_meta,
432 $common_ancestor,
433 );
434 }
435
436 return 1;
437}
438
439# This, and some other functions, could be called as methods, but
440# they're not for two reasons. One, we just end up ignoring the first
441# argument, because we can't call these directly on one of the real
442# arguments, because one of them could be a Class::MOP::Class object
443# and not a Moose::Meta::Class. Second, only a completely insane
444# person would attempt to subclass this stuff!
445sub _find_common_ancestor {
446 my ($meta1, $meta2) = @_;
447
448 # FIXME? This doesn't account for multiple inheritance (not sure
449 # if it needs to though). For example, is somewhere in $meta1's
450 # history it inherits from both ClassA and ClassB, and $meta
451 # inherits from ClassB & ClassA, does it matter? And what crazy
452 # fool would do that anyway?
453
454 my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
455
456 return first { $meta1_parents{$_} } $meta2->linearized_isa;
457}
458
459sub _is_role_only_subclass_of {
460 my ($meta, $ancestor) = @_;
461
462 return 1 if $meta->name eq $ancestor;
463
464 my @roles = _all_roles_until( $meta, $ancestor );
465
466 my %role_packages = map { $_->name => 1 } @roles;
467
468 my $ancestor_meta = Class::MOP::Class->initialize($ancestor);
469
470 my %shared_ancestors = map { $_ => 1 } $ancestor_meta->linearized_isa;
471
472 for my $method ( $meta->get_all_methods() ) {
473 next if $method->name eq 'meta';
474 next if $method->can('associated_attribute');
475
476 next
477 if $role_packages{ $method->original_package_name }
478 || $shared_ancestors{ $method->original_package_name };
479
480 return 0;
481 }
482
483 # FIXME - this really isn't right. Just because an attribute is
484 # defined in a role doesn't mean it isn't _also_ defined in the
485 # subclass.
486 for my $attr ( $meta->get_all_attributes ) {
487 next if $shared_ancestors{ $attr->associated_class->name };
488
489 next if any { $_->has_attribute( $attr->name ) } @roles;
490
491 return 0;
492 }
493
494 return 1;
495}
496
497sub _all_roles {
498 my $meta = shift;
499
500 return _all_roles_until($meta);
501}
502
503sub _all_roles_until {
504 my ($meta, $stop_at_class) = @_;
505
506 return unless $meta->can('calculate_all_roles');
507
508 my @roles = $meta->calculate_all_roles;
509
510 for my $class ( $meta->linearized_isa ) {
511 last if $stop_at_class && $stop_at_class eq $class;
512
513 my $meta = Class::MOP::Class->initialize($class);
514 last unless $meta->can('calculate_all_roles');
515
516 push @roles, $meta->calculate_all_roles;
517 }
518
8b1d510f 519 return uniq @roles;
f8b6827f 520}
521
522sub _reconcile_role_differences {
523 my ($self, $super_meta) = @_;
524
525 my $self_meta = $self->meta;
526
527 my %roles;
528
529 if ( my @roles = map { $_->name } _all_roles($self_meta) ) {
530 $roles{metaclass_roles} = \@roles;
531 }
532
533 for my $thing (@MetaClassTypes) {
534 my $name = $self->$thing();
535
536 my $thing_meta = Class::MOP::Class->initialize($name);
537
538 my @roles = map { $_->name } _all_roles($thing_meta)
539 or next;
540
541 $roles{ $thing . '_roles' } = \@roles;
542 }
543
2b72f3b4 544 $self->_reinitialize_with($super_meta);
f8b6827f 545
546 Moose::Util::MetaRole::apply_metaclass_roles(
547 for_class => $self->name,
548 %roles,
549 );
550
551 return $self;
552}
553
d7d8a8c7 554# NOTE:
d9bb6c63 555# this was crap anyway, see
556# Moose::Util::apply_all_roles
d7d8a8c7 557# instead
4498537c 558sub _apply_all_roles {
547dda77 559 Carp::croak 'DEPRECATED: use Moose::Util::apply_all_roles($meta, @roles) instead'
4498537c 560}
1341f10c 561
562sub _process_attribute {
a3738e5b 563 my ( $self, $name, @args ) = @_;
7e59b803 564
565 @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
d9bb6c63 566
f9b5f5f8 567 if (($name || '') =~ /^\+(.*)/) {
7e59b803 568 return $self->_process_inherited_attribute($1, @args);
1341f10c 569 }
570 else {
7e59b803 571 return $self->_process_new_attribute($name, @args);
572 }
573}
574
575sub _process_new_attribute {
576 my ( $self, $name, @args ) = @_;
7e59b803 577
d5c30e52 578 $self->attribute_metaclass->interpolate_class_and_new($name, @args);
1341f10c 579}
580
581sub _process_inherited_attribute {
582 my ($self, $attr_name, %options) = @_;
583 my $inherited_attr = $self->find_attribute_by_name($attr_name);
584 (defined $inherited_attr)
11c86f15 585 || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from", data => $attr_name);
1341f10c 586 if ($inherited_attr->isa('Moose::Meta::Attribute')) {
d7d8a8c7 587 return $inherited_attr->clone_and_inherit_options(%options);
1341f10c 588 }
589 else {
590 # NOTE:
591 # kind of a kludge to handle Class::MOP::Attributes
d7d8a8c7 592 return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
ac2dc464 593 }
1341f10c 594}
595
5cf3dbcf 596## -------------------------------------------------
597
598use Moose::Meta::Method::Constructor;
1f779926 599use Moose::Meta::Method::Destructor;
5cf3dbcf 600
ac2dc464 601# This could be done by using SUPER and altering ->options
602# I am keeping it this way to make it more explicit.
603sub create_immutable_transformer {
604 my $self = shift;
605 my $class = Class::MOP::Immutable->new($self, {
e606ae5f 606 read_only => [qw/superclasses/],
607 cannot_call => [qw/
608 add_method
609 alias_method
610 remove_method
611 add_attribute
612 remove_attribute
613 remove_package_symbol
614 add_role
615 /],
616 memoize => {
617 class_precedence_list => 'ARRAY',
618 linearized_isa => 'ARRAY', # FIXME perl 5.10 memoizes this on its own, no need?
619 get_all_methods => 'ARRAY',
620 #get_all_attributes => 'ARRAY', # it's an alias, no need, but maybe in the future
621 compute_all_applicable_attributes => 'ARRAY',
622 get_meta_instance => 'SCALAR',
623 get_method_map => 'SCALAR',
624 calculate_all_roles => 'ARRAY',
625 },
626 # NOTE:
627 # this is ugly, but so are typeglobs,
628 # so whattayahgonnadoboutit
629 # - SL
630 wrapped => {
631 add_package_symbol => sub {
632 my $original = shift;
633 $self->throw_error("Cannot add package symbols to an immutable metaclass")
634 unless (caller(2))[3] eq 'Class::MOP::Package::get_package_symbol';
635 goto $original->body;
636 },
637 },
ac2dc464 638 });
639 return $class;
640}
641
642sub make_immutable {
643 my $self = shift;
644 $self->SUPER::make_immutable
645 (
e606ae5f 646 constructor_class => $self->constructor_class,
647 destructor_class => $self->destructor_class,
ac2dc464 648 inline_destructor => 1,
649 # NOTE:
650 # no need to do this,
651 # Moose always does it
652 inline_accessors => 0,
653 @_,
654 );
5cf3dbcf 655}
656
bf6fa6b3 657our $error_level;
11c86f15 658
659sub throw_error {
660 my ( $self, @args ) = @_;
bf6fa6b3 661 local $error_level = ($error_level || 0) + 1;
11c86f15 662 $self->raise_error($self->create_error(@args));
663}
664
665sub raise_error {
666 my ( $self, @args ) = @_;
667 die @args;
668}
669
670sub create_error {
671 my ( $self, @args ) = @_;
672
18748ad6 673 require Carp::Heavy;
674
bf6fa6b3 675 local $error_level = ($error_level || 0 ) + 1;
18748ad6 676
11c86f15 677 if ( @args % 2 == 1 ) {
678 unshift @args, "message";
679 }
680
fcab1742 681 my %args = ( metaclass => $self, last_error => $@, @args );
11c86f15 682
bf6fa6b3 683 $args{depth} += $error_level;
11c86f15 684
bf6fa6b3 685 my $class = ref $self ? $self->error_class : "Moose::Error::Default";
11c86f15 686
a810a01f 687 Class::MOP::load_class($class);
688
11c86f15 689 $class->new(
bf6fa6b3 690 Carp::caller_info($args{depth}),
691 %args
11c86f15 692 );
693}
694
c0e30cf5 6951;
696
697__END__
698
699=pod
700
701=head1 NAME
702
e522431d 703Moose::Meta::Class - The Moose metaclass
c0e30cf5 704
c0e30cf5 705=head1 DESCRIPTION
706
ac2dc464 707This is a subclass of L<Class::MOP::Class> with Moose specific
e522431d 708extensions.
709
ac2dc464 710For the most part, the only time you will ever encounter an
711instance of this class is if you are doing some serious deep
712introspection. To really understand this class, you need to refer
6ba6d68c 713to the L<Class::MOP::Class> documentation.
714
c0e30cf5 715=head1 METHODS
716
717=over 4
718
590868a3 719=item B<initialize>
720
61bdd94f 721=item B<create>
722
17594769 723Overrides original to accept a list of roles to apply to
61bdd94f 724the created class.
725
17594769 726 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
727
728=item B<create_anon_class>
729
730Overrides original to support roles and caching.
731
732 my $metaclass = Moose::Meta::Class->create_anon_class(
733 superclasses => ['Foo'],
734 roles => [qw/Some Roles Go Here/],
735 cache => 1,
736 );
737
5cf3dbcf 738=item B<make_immutable>
739
ac2dc464 740Override original to add default options for inlining destructor
741and altering the Constructor metaclass.
742
743=item B<create_immutable_transformer>
744
745Override original to lock C<add_role> and memoize C<calculate_all_roles>
746
8c9d74e7 747=item B<new_object>
748
02a0fb52 749We override this method to support the C<trigger> attribute option.
750
a15dff8d 751=item B<construct_instance>
752
ac2dc464 753This provides some Moose specific extensions to this method, you
754almost never call this method directly unless you really know what
755you are doing.
6ba6d68c 756
757This method makes sure to handle the moose weak-ref, type-constraint
ac2dc464 758and type coercion features.
ef1d5f4b 759
093b12c2 760=item B<get_method_map>
e9ec68d6 761
ac2dc464 762This accommodates Moose::Meta::Role::Method instances, which are
763aliased, instead of added, but still need to be counted as valid
e9ec68d6 764methods.
765
78cd1d3b 766=item B<add_override_method_modifier ($name, $method)>
767
ac2dc464 768This will create an C<override> method modifier for you, and install
02a0fb52 769it in the package.
770
78cd1d3b 771=item B<add_augment_method_modifier ($name, $method)>
772
ac2dc464 773This will create an C<augment> method modifier for you, and install
02a0fb52 774it in the package.
775
2b14ac61 776=item B<calculate_all_roles>
777
ef333f17 778=item B<roles>
779
ac2dc464 780This will return an array of C<Moose::Meta::Role> instances which are
02a0fb52 781attached to this class.
782
ef333f17 783=item B<add_role ($role)>
784
ac2dc464 785This takes an instance of C<Moose::Meta::Role> in C<$role>, and adds it
02a0fb52 786to the list of associated roles.
787
ef333f17 788=item B<does_role ($role_name)>
789
ac2dc464 790This will test if this class C<does> a given C<$role_name>. It will
791not only check it's local roles, but ask them as well in order to
02a0fb52 792cascade down the role hierarchy.
793
d79e62fd 794=item B<excludes_role ($role_name)>
795
ac2dc464 796This will test if this class C<excludes> a given C<$role_name>. It will
797not only check it's local roles, but ask them as well in order to
d79e62fd 798cascade down the role hierarchy.
799
9e93dd19 800=item B<add_attribute ($attr_name, %params|$params)>
4e848edb 801
9e93dd19 802This method does the same thing as L<Class::MOP::Class::add_attribute>, but adds
803support for taking the C<$params> as a HASH ref.
ac1ef2f9 804
e606ae5f 805=item B<constructor_class ($class_name)>
806
807=item B<destructor_class ($class_name)>
808
809These are the names of classes used when making a class
810immutable. These default to L<Moose::Meta::Method::Constructor> and
811L<Moose::Meta::Method::Destructor> respectively. These accessors are
812read-write, so you can use them to change the class name.
813
8b1d510f 814=item B<error_class ($class_name)>
815
816The name of the class used to throw errors. This default to
817L<Moose::Error::Default>, which generates an error with a stacktrace
818just like C<Carp::confess>.
819
4fb87686 820=item B<check_metaclass_compatibility>
821
822Moose overrides this method from C<Class::MOP::Class> and attempts to
823fix some incompatibilities before doing the check.
824
11c86f15 825=item B<throw_error $message, %extra>
826
827Throws the error created by C<create_error> using C<raise_error>
828
829=item B<create_error $message, %extra>
830
831Creates an error message or object.
832
833The default behavior is C<create_error_confess>.
834
835If C<error_class> is set uses C<create_error_object>. Otherwise uses
836C<error_builder> (a code reference or variant name), and calls the appropriate
837C<create_error_$builder> method.
838
839=item B<error_builder $builder_name>
840
841Get or set the error builder. Defaults to C<confess>.
842
843=item B<error_class $class_name>
844
845Get or set the error class. Has no default.
846
847=item B<create_error_confess %args>
848
849Creates an error using L<Carp/longmess>
850
851=item B<create_error_croak %args>
852
853Creates an error using L<Carp/shortmess>
854
855=item B<create_error_object %args>
856
857Calls C<new> on the C<class> parameter in C<%args>. Usable with C<error_class>
858to support custom error objects for your meta class.
859
860=item B<raise_error $error>
861
862Dies with an error object or string.
863
c0e30cf5 864=back
865
866=head1 BUGS
867
ac2dc464 868All complex software has bugs lurking in it, and this module is no
c0e30cf5 869exception. If you find a bug please either email me, or add the bug
870to cpan-RT.
871
c0e30cf5 872=head1 AUTHOR
873
874Stevan Little E<lt>stevan@iinteractive.comE<gt>
875
876=head1 COPYRIGHT AND LICENSE
877
778db3ac 878Copyright 2006-2008 by Infinity Interactive, Inc.
c0e30cf5 879
880L<http://www.iinteractive.com>
881
882This library is free software; you can redistribute it and/or modify
ac2dc464 883it under the same terms as Perl itself.
c0e30cf5 884
8a7a9c53 885=cut
1a563243 886