Add date to Changes
[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
0aca6c89 14our $VERSION = '0.74';
e606ae5f 15$VERSION = eval $VERSION;
d44714be 16our $AUTHORITY = 'cpan:STEVAN';
bc1e29b5 17
74862722 18use Moose::Meta::Method::Overridden;
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
6a4a7c31 74sub _check_metaclass_compatibility {
2b72f3b4 75 my $self = shift;
76
77 if ( my @supers = $self->superclasses ) {
78 $self->_fix_metaclass_incompatibility(@supers);
79 }
80
6a4a7c31 81 $self->SUPER::_check_metaclass_compatibility(@_);
2b72f3b4 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 '=' => (
11aaed6c 93 join('|', @{$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) = @_;
322abb07 124
ef333f17 125 (defined $role_name)
11c86f15 126 || $self->throw_error("You must supply a role name to look for");
322abb07 127
9c429218 128 foreach my $class ($self->class_precedence_list) {
322abb07 129 my $meta = Class::MOP::class_of($class);
3d0f5a27 130 # when a Moose metaclass is itself extended with a role,
131 # this check needs to be done since some items in the
132 # class_precedence_list might in fact be Class::MOP
133 # based still.
322abb07 134 next unless $meta && $meta->can('roles');
135 foreach my $role (@{$meta->roles}) {
9c429218 136 return 1 if $role->does_role($role_name);
137 }
ef333f17 138 }
139 return 0;
140}
141
d79e62fd 142sub excludes_role {
143 my ($self, $role_name) = @_;
ebfc4d0f 144
d79e62fd 145 (defined $role_name)
11c86f15 146 || $self->throw_error("You must supply a role name to look for");
ebfc4d0f 147
ac2dc464 148 foreach my $class ($self->class_precedence_list) {
ebfc4d0f 149 my $meta = Class::MOP::class_of($class);
150 # when a Moose metaclass is itself extended with a role,
151 # this check needs to be done since some items in the
152 # class_precedence_list might in fact be Class::MOP
153 # based still.
154 next unless $meta && $meta->can('roles');
155 foreach my $role (@{$meta->roles}) {
9c429218 156 return 1 if $role->excludes_role($role_name);
157 }
d79e62fd 158 }
159 return 0;
160}
161
8c9d74e7 162sub new_object {
1308deb4 163 my $class = shift;
e606ae5f 164 my $params = @_ == 1 ? $_[0] : {@_};
1308deb4 165 my $self = $class->SUPER::new_object($params);
166
b2df9268 167 foreach my $attr ( $class->get_all_attributes() ) {
1308deb4 168
169 next unless $attr->can('has_trigger') && $attr->has_trigger;
170
171 my $init_arg = $attr->init_arg;
172
173 next unless defined $init_arg;
174
175 next unless exists $params->{$init_arg};
176
177 $attr->trigger->(
178 $self,
179 (
180 $attr->should_coerce
181 ? $attr->get_read_method_ref->($self)
182 : $params->{$init_arg}
183 ),
1308deb4 184 );
8c9d74e7 185 }
1308deb4 186
ac2dc464 187 return $self;
8c9d74e7 188}
189
b2df9268 190sub _construct_instance {
e606ae5f 191 my $class = shift;
192 my $params = @_ == 1 ? $_[0] : {@_};
ddd0ec20 193 my $meta_instance = $class->get_meta_instance;
575db57d 194 # FIXME:
195 # the code below is almost certainly incorrect
6549b0d1 196 # but this is foreign inheritance, so we might
ac2dc464 197 # have to kludge it in the end.
e606ae5f 198 my $instance = $params->{'__INSTANCE__'} || $meta_instance->create_instance();
b2df9268 199 foreach my $attr ($class->get_all_attributes()) {
e606ae5f 200 $attr->initialize_instance_slot($meta_instance, $instance, $params);
a15dff8d 201 }
202 return $instance;
203}
204
e2eef3a5 205sub superclasses {
206 my $self = shift;
207 my @supers = @_;
208 foreach my $super (@supers) {
209 my $meta = Class::MOP::load_class($super);
210 Moose->throw_error("You cannot inherit from a Moose Role ($super)")
211 if $meta && $meta->isa('Moose::Meta::Role')
212 }
213 return $self->SUPER::superclasses(@supers);
214}
215
093b12c2 216### ---------------------------------------------
217
a2eec5e7 218sub add_attribute {
219 my $self = shift;
e472c9a5 220 $self->SUPER::add_attribute(
221 (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
222 ? $_[0]
223 : $self->_process_attribute(@_))
224 );
a2eec5e7 225}
226
78cd1d3b 227sub add_override_method_modifier {
228 my ($self, $name, $method, $_super_package) = @_;
18c2ec0e 229
d05cd563 230 (!$self->has_method($name))
11c86f15 231 || $self->throw_error("Cannot add an override method if a local method is already present");
18c2ec0e 232
74862722 233 $self->add_method($name => Moose::Meta::Method::Overridden->new(
3f9e4b0a 234 method => $method,
235 class => $self,
236 package => $_super_package, # need this for roles
237 name => $name,
18c2ec0e 238 ));
78cd1d3b 239}
240
241sub add_augment_method_modifier {
ac2dc464 242 my ($self, $name, $method) = @_;
d05cd563 243 (!$self->has_method($name))
11c86f15 244 || $self->throw_error("Cannot add an augment method if a local method is already present");
3f9e4b0a 245
246 $self->add_method($name => Moose::Meta::Method::Augmented->new(
247 method => $method,
248 class => $self,
249 name => $name,
250 ));
78cd1d3b 251}
252
1341f10c 253## Private Utility methods ...
254
05d9eaf6 255sub _find_next_method_by_name_which_is_not_overridden {
256 my ($self, $name) = @_;
68efb014 257 foreach my $method ($self->find_all_methods_by_name($name)) {
ac2dc464 258 return $method->{code}
74862722 259 if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
05d9eaf6 260 }
261 return undef;
262}
263
41419b9e 264sub _fix_metaclass_incompatibility {
1341f10c 265 my ($self, @superclasses) = @_;
e606ae5f 266
1341f10c 267 foreach my $super (@superclasses) {
f8b6827f 268 next if $self->_superclass_meta_is_compatible($super);
e606ae5f 269
270 unless ( $self->is_pristine ) {
f8b6827f 271 $self->throw_error(
272 "Cannot attempt to reinitialize metaclass for "
273 . $self->name
274 . ", it isn't pristine" );
1341f10c 275 }
e606ae5f 276
0635500e 277 $self->_reconcile_with_superclass_meta($super);
f8b6827f 278 }
f8b6827f 279}
280
281sub _superclass_meta_is_compatible {
282 my ($self, $super) = @_;
283
284 my $super_meta = Class::MOP::Class->initialize($super)
285 or return 1;
286
287 next unless $super_meta->isa("Class::MOP::Class");
288
289 my $super_meta_name
290 = $super_meta->is_immutable
291 ? $super_meta->get_mutable_metaclass_name
292 : ref($super_meta);
293
294 return 1
295 if $self->isa($super_meta_name)
296 and
297 $self->instance_metaclass->isa( $super_meta->instance_metaclass );
298}
299
300# I don't want to have to type this >1 time
301my @MetaClassTypes =
8b1d510f 302 qw( attribute_metaclass method_metaclass instance_metaclass
303 constructor_class destructor_class error_class );
f8b6827f 304
305sub _reconcile_with_superclass_meta {
306 my ($self, $super) = @_;
307
29782f74 308 my $super_meta = Class::MOP::class_of($super);
f8b6827f 309
dd37a5be 310 my $super_meta_name
f8b6827f 311 = $super_meta->is_immutable
312 ? $super_meta->get_mutable_metaclass_name
313 : ref($super_meta);
e606ae5f 314
f8b6827f 315 my $self_metaclass = ref $self;
316
317 # If neither of these is true we have a more serious
318 # incompatibility that we just cannot fix (yet?).
dd37a5be 319 if ( $super_meta_name->isa( ref $self )
f8b6827f 320 && all { $super_meta->$_->isa( $self->$_ ) } @MetaClassTypes ) {
0635500e 321 $self->_reinitialize_with($super_meta);
f8b6827f 322 }
323 elsif ( $self->_all_metaclasses_differ_by_roles_only($super_meta) ) {
0635500e 324 $self->_reconcile_role_differences($super_meta);
1341f10c 325 }
1341f10c 326}
327
f8b6827f 328sub _reinitialize_with {
329 my ( $self, $new_meta ) = @_;
330
0635500e 331 my $new_self = $new_meta->reinitialize(
f8b6827f 332 $self->name,
333 attribute_metaclass => $new_meta->attribute_metaclass,
334 method_metaclass => $new_meta->method_metaclass,
335 instance_metaclass => $new_meta->instance_metaclass,
336 );
337
8b1d510f 338 $new_self->$_( $new_meta->$_ )
339 for qw( constructor_class destructor_class error_class );
f8b6827f 340
0635500e 341 %$self = %$new_self;
342
343 bless $self, ref $new_self;
344
4c5fcc12 345 # We need to replace the cached metaclass instance or else when it
346 # goes out of scope Class::MOP::Class destroy's the namespace for
347 # the metaclass's class, causing much havoc.
0635500e 348 Class::MOP::store_metaclass_by_name( $self->name, $self );
4c5fcc12 349 Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class;
f8b6827f 350}
351
352# In the more complex case, we share a common ancestor with our
353# superclass's metaclass, but each metaclass (ours and the parent's)
354# has a different set of roles applied. We reconcile this by first
355# reinitializing into the parent class, and _then_ applying our own
356# roles.
357sub _all_metaclasses_differ_by_roles_only {
358 my ($self, $super_meta) = @_;
359
360 for my $pair (
361 [ ref $self, ref $super_meta ],
362 map { [ $self->$_, $super_meta->$_ ] } @MetaClassTypes
363 ) {
364
365 next if $pair->[0] eq $pair->[1];
366
367 my $self_meta_meta = Class::MOP::Class->initialize( $pair->[0] );
368 my $super_meta_meta = Class::MOP::Class->initialize( $pair->[1] );
369
370 my $common_ancestor
371 = _find_common_ancestor( $self_meta_meta, $super_meta_meta );
372
373 return unless $common_ancestor;
374
375 return
376 unless _is_role_only_subclass_of(
377 $self_meta_meta,
378 $common_ancestor,
379 )
380 && _is_role_only_subclass_of(
381 $super_meta_meta,
382 $common_ancestor,
383 );
384 }
385
386 return 1;
387}
388
389# This, and some other functions, could be called as methods, but
390# they're not for two reasons. One, we just end up ignoring the first
391# argument, because we can't call these directly on one of the real
392# arguments, because one of them could be a Class::MOP::Class object
393# and not a Moose::Meta::Class. Second, only a completely insane
394# person would attempt to subclass this stuff!
395sub _find_common_ancestor {
396 my ($meta1, $meta2) = @_;
397
398 # FIXME? This doesn't account for multiple inheritance (not sure
399 # if it needs to though). For example, is somewhere in $meta1's
db9fda52 400 # history it inherits from both ClassA and ClassB, and $meta2
f8b6827f 401 # inherits from ClassB & ClassA, does it matter? And what crazy
402 # fool would do that anyway?
403
404 my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
405
406 return first { $meta1_parents{$_} } $meta2->linearized_isa;
407}
408
409sub _is_role_only_subclass_of {
410 my ($meta, $ancestor) = @_;
411
412 return 1 if $meta->name eq $ancestor;
413
414 my @roles = _all_roles_until( $meta, $ancestor );
415
416 my %role_packages = map { $_->name => 1 } @roles;
417
418 my $ancestor_meta = Class::MOP::Class->initialize($ancestor);
419
420 my %shared_ancestors = map { $_ => 1 } $ancestor_meta->linearized_isa;
421
422 for my $method ( $meta->get_all_methods() ) {
423 next if $method->name eq 'meta';
424 next if $method->can('associated_attribute');
425
426 next
427 if $role_packages{ $method->original_package_name }
428 || $shared_ancestors{ $method->original_package_name };
429
430 return 0;
431 }
432
433 # FIXME - this really isn't right. Just because an attribute is
434 # defined in a role doesn't mean it isn't _also_ defined in the
435 # subclass.
436 for my $attr ( $meta->get_all_attributes ) {
437 next if $shared_ancestors{ $attr->associated_class->name };
438
439 next if any { $_->has_attribute( $attr->name ) } @roles;
440
441 return 0;
442 }
443
444 return 1;
445}
446
447sub _all_roles {
448 my $meta = shift;
449
450 return _all_roles_until($meta);
451}
452
453sub _all_roles_until {
454 my ($meta, $stop_at_class) = @_;
455
456 return unless $meta->can('calculate_all_roles');
457
458 my @roles = $meta->calculate_all_roles;
459
460 for my $class ( $meta->linearized_isa ) {
461 last if $stop_at_class && $stop_at_class eq $class;
462
463 my $meta = Class::MOP::Class->initialize($class);
464 last unless $meta->can('calculate_all_roles');
465
466 push @roles, $meta->calculate_all_roles;
467 }
468
8b1d510f 469 return uniq @roles;
f8b6827f 470}
471
472sub _reconcile_role_differences {
473 my ($self, $super_meta) = @_;
474
3897e146 475 my $self_meta = Class::MOP::class_of($self);
f8b6827f 476
477 my %roles;
478
479 if ( my @roles = map { $_->name } _all_roles($self_meta) ) {
480 $roles{metaclass_roles} = \@roles;
481 }
482
483 for my $thing (@MetaClassTypes) {
484 my $name = $self->$thing();
485
486 my $thing_meta = Class::MOP::Class->initialize($name);
487
488 my @roles = map { $_->name } _all_roles($thing_meta)
489 or next;
490
491 $roles{ $thing . '_roles' } = \@roles;
492 }
493
2b72f3b4 494 $self->_reinitialize_with($super_meta);
f8b6827f 495
496 Moose::Util::MetaRole::apply_metaclass_roles(
497 for_class => $self->name,
498 %roles,
499 );
500
501 return $self;
502}
503
1341f10c 504sub _process_attribute {
a3738e5b 505 my ( $self, $name, @args ) = @_;
7e59b803 506
507 @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
d9bb6c63 508
f9b5f5f8 509 if (($name || '') =~ /^\+(.*)/) {
7e59b803 510 return $self->_process_inherited_attribute($1, @args);
1341f10c 511 }
512 else {
7e59b803 513 return $self->_process_new_attribute($name, @args);
514 }
515}
516
517sub _process_new_attribute {
518 my ( $self, $name, @args ) = @_;
7e59b803 519
d5c30e52 520 $self->attribute_metaclass->interpolate_class_and_new($name, @args);
1341f10c 521}
522
523sub _process_inherited_attribute {
524 my ($self, $attr_name, %options) = @_;
525 my $inherited_attr = $self->find_attribute_by_name($attr_name);
526 (defined $inherited_attr)
329c5dd4 527 || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
1341f10c 528 if ($inherited_attr->isa('Moose::Meta::Attribute')) {
d7d8a8c7 529 return $inherited_attr->clone_and_inherit_options(%options);
1341f10c 530 }
531 else {
532 # NOTE:
533 # kind of a kludge to handle Class::MOP::Attributes
d7d8a8c7 534 return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
ac2dc464 535 }
1341f10c 536}
537
5cf3dbcf 538## -------------------------------------------------
539
540use Moose::Meta::Method::Constructor;
1f779926 541use Moose::Meta::Method::Destructor;
5cf3dbcf 542
ac2dc464 543
70695d9c 544sub _default_immutable_transformer_options {
ac2dc464 545 my $self = shift;
70695d9c 546
547 my %options = $self->SUPER::_default_immutable_transformer_options;
548
549 # We need to copy the references as we do not want to alter the
550 # superclass's references.
551 $options{cannot_call} = [ @{ $options{cannot_call} }, 'add_role' ];
552 $options{memoize} = {
553 %{ $options{memoize} },
554 calculate_all_roles => 'ARRAY',
555 };
556
557 %options = (
558 %options,
559 constructor_class => $self->constructor_class,
560 destructor_class => $self->destructor_class,
561 inline_destructor => 1,
562
563 # Moose always does this when an attribute is created
564 inline_accessors => 0,
565 );
566
567 return %options
5cf3dbcf 568}
569
bf6fa6b3 570our $error_level;
11c86f15 571
572sub throw_error {
573 my ( $self, @args ) = @_;
bf6fa6b3 574 local $error_level = ($error_level || 0) + 1;
11c86f15 575 $self->raise_error($self->create_error(@args));
576}
577
578sub raise_error {
579 my ( $self, @args ) = @_;
580 die @args;
581}
582
583sub create_error {
584 my ( $self, @args ) = @_;
585
18748ad6 586 require Carp::Heavy;
587
bf6fa6b3 588 local $error_level = ($error_level || 0 ) + 1;
18748ad6 589
11c86f15 590 if ( @args % 2 == 1 ) {
591 unshift @args, "message";
592 }
593
fcab1742 594 my %args = ( metaclass => $self, last_error => $@, @args );
11c86f15 595
bf6fa6b3 596 $args{depth} += $error_level;
11c86f15 597
bf6fa6b3 598 my $class = ref $self ? $self->error_class : "Moose::Error::Default";
11c86f15 599
a810a01f 600 Class::MOP::load_class($class);
601
11c86f15 602 $class->new(
bf6fa6b3 603 Carp::caller_info($args{depth}),
604 %args
11c86f15 605 );
606}
607
c0e30cf5 6081;
609
610__END__
611
612=pod
613
614=head1 NAME
615
e522431d 616Moose::Meta::Class - The Moose metaclass
c0e30cf5 617
c0e30cf5 618=head1 DESCRIPTION
619
70bb0f97 620This class is a subclass of L<Class::MOP::Class> that provides
621additional Moose-specific functionality.
e522431d 622
7854b409 623To really understand this class, you will need to start with the
624L<Class::MOP::Class> documentation. This class can be understood as a
625set of additional features on top of the basic feature provided by
626that parent class.
6ba6d68c 627
d4b1449e 628=head1 INHERITANCE
629
630C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
631
c0e30cf5 632=head1 METHODS
633
634=over 4
635
70bb0f97 636=item B<< Moose::Meta::Class->initialize($package_name, %options) >>
590868a3 637
70bb0f97 638This overrides the parent's method in order to provide its own
639defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
640C<method_metaclass> options.
61bdd94f 641
70bb0f97 642These all default to the appropriate Moose class.
61bdd94f 643
70bb0f97 644=item B<< Moose::Meta::Class->create($package_name, %options) >>
17594769 645
70bb0f97 646This overrides the parent's method in order to accept a C<roles>
647option. This should be an array reference containing one more roles
648that the class does.
17594769 649
70bb0f97 650 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
17594769 651
70bb0f97 652=item B<< Moose::Meta::Class->create_anon_class >>
17594769 653
70bb0f97 654This overrides the parent's method to accept a C<roles> option, just
655as C<create> does.
5cf3dbcf 656
70bb0f97 657It also accepts a C<cache> option. If this is true, then the anonymous
658class will be cached based on its superclasses and roles. If an
659existing anonymous class in the cache has the same superclasses and
660roles, it will be reused.
ac2dc464 661
70bb0f97 662 my $metaclass = Moose::Meta::Class->create_anon_class(
663 superclasses => ['Foo'],
664 roles => [qw/Some Roles Go Here/],
665 cache => 1,
666 );
ac2dc464 667
70bb0f97 668=item B<< $metaclass->make_immutable(%options) >>
ac2dc464 669
70bb0f97 670This overrides the parent's method to add a few options. Specifically,
671it uses the Moose-specific constructor and destructor classes, and
672enables inlining the destructor.
8c9d74e7 673
70bb0f97 674Also, since Moose always inlines attributes, it sets the
675C<inline_accessors> option to false.
02a0fb52 676
70bb0f97 677=item B<< $metaclass->new_object(%params) >>
a15dff8d 678
70bb0f97 679This overrides the parent's method in order to add support for
680attribute triggers.
6ba6d68c 681
70bb0f97 682=item B<< $metaclass->add_override_method_modifier($name, $sub) >>
ef1d5f4b 683
70bb0f97 684This adds an C<override> method modifier to the package.
e9ec68d6 685
70bb0f97 686=item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
e9ec68d6 687
70bb0f97 688This adds an C<augment> method modifier to the package.
78cd1d3b 689
70bb0f97 690=item B<< $metaclass->calculate_all_roles >>
02a0fb52 691
70bb0f97 692This will return a unique array of C<Moose::Meta::Role> instances
693which are attached to this class.
78cd1d3b 694
70bb0f97 695=item B<< $metaclass->add_role($role) >>
02a0fb52 696
70bb0f97 697This takes a L<Moose::Meta::Role> object, and adds it to the class's
698list of roles. This I<does not> actually apply the role to the class.
2b14ac61 699
70bb0f97 700=item B<< $metaclass->does_role($role_name) >>
ef333f17 701
70bb0f97 702This returns a boolean indicating whether or not the class does the
703specified role. This tests both the class and its parents.
02a0fb52 704
70bb0f97 705=item B<< $metaclass->excludes_role($role_name) >>
ef333f17 706
70bb0f97 707A class excludes a role if it has already composed a role which
708excludes the named role. This tests both the class and its parents.
02a0fb52 709
70bb0f97 710=item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
ef333f17 711
70bb0f97 712This overrides the parent's method in order to allow the parameters to
713be provided as a hash reference.
02a0fb52 714
70bb0f97 715=item B<< $metaclass->constructor_class ($class_name) >>
d79e62fd 716
70bb0f97 717=item B<< $metaclass->destructor_class ($class_name) >>
e606ae5f 718
719These are the names of classes used when making a class
720immutable. These default to L<Moose::Meta::Method::Constructor> and
721L<Moose::Meta::Method::Destructor> respectively. These accessors are
722read-write, so you can use them to change the class name.
723
70bb0f97 724=item B<< $metaclass->error_class($class_name) >>
8b1d510f 725
70bb0f97 726The name of the class used to throw errors. This defaults to
8b1d510f 727L<Moose::Error::Default>, which generates an error with a stacktrace
728just like C<Carp::confess>.
729
70bb0f97 730=item B<< $metaclass->throw_error($message, %extra) >>
11c86f15 731
732Throws the error created by C<create_error> using C<raise_error>
733
c0e30cf5 734=back
735
736=head1 BUGS
737
ac2dc464 738All complex software has bugs lurking in it, and this module is no
c0e30cf5 739exception. If you find a bug please either email me, or add the bug
740to cpan-RT.
741
c0e30cf5 742=head1 AUTHOR
743
744Stevan Little E<lt>stevan@iinteractive.comE<gt>
745
746=head1 COPYRIGHT AND LICENSE
747
2840a3b2 748Copyright 2006-2009 by Infinity Interactive, Inc.
c0e30cf5 749
750L<http://www.iinteractive.com>
751
752This library is free software; you can redistribute it and/or modify
ac2dc464 753it under the same terms as Perl itself.
c0e30cf5 754
8a7a9c53 755=cut
1a563243 756