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