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