Merge branch 'refactor-immutable'
[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
70695d9c 534sub _default_immutable_transformer_options {
ac2dc464 535 my $self = shift;
70695d9c 536
537 my %options = $self->SUPER::_default_immutable_transformer_options;
538
539 # We need to copy the references as we do not want to alter the
540 # superclass's references.
541 $options{cannot_call} = [ @{ $options{cannot_call} }, 'add_role' ];
542 $options{memoize} = {
543 %{ $options{memoize} },
544 calculate_all_roles => 'ARRAY',
545 };
546
547 %options = (
548 %options,
549 constructor_class => $self->constructor_class,
550 destructor_class => $self->destructor_class,
551 inline_destructor => 1,
552
553 # Moose always does this when an attribute is created
554 inline_accessors => 0,
555 );
556
557 return %options
5cf3dbcf 558}
559
bf6fa6b3 560our $error_level;
11c86f15 561
562sub throw_error {
563 my ( $self, @args ) = @_;
bf6fa6b3 564 local $error_level = ($error_level || 0) + 1;
11c86f15 565 $self->raise_error($self->create_error(@args));
566}
567
568sub raise_error {
569 my ( $self, @args ) = @_;
570 die @args;
571}
572
573sub create_error {
574 my ( $self, @args ) = @_;
575
18748ad6 576 require Carp::Heavy;
577
bf6fa6b3 578 local $error_level = ($error_level || 0 ) + 1;
18748ad6 579
11c86f15 580 if ( @args % 2 == 1 ) {
581 unshift @args, "message";
582 }
583
fcab1742 584 my %args = ( metaclass => $self, last_error => $@, @args );
11c86f15 585
bf6fa6b3 586 $args{depth} += $error_level;
11c86f15 587
bf6fa6b3 588 my $class = ref $self ? $self->error_class : "Moose::Error::Default";
11c86f15 589
a810a01f 590 Class::MOP::load_class($class);
591
11c86f15 592 $class->new(
bf6fa6b3 593 Carp::caller_info($args{depth}),
594 %args
11c86f15 595 );
596}
597
c0e30cf5 5981;
599
600__END__
601
602=pod
603
604=head1 NAME
605
e522431d 606Moose::Meta::Class - The Moose metaclass
c0e30cf5 607
c0e30cf5 608=head1 DESCRIPTION
609
70bb0f97 610This class is a subclass of L<Class::MOP::Class> that provides
611additional Moose-specific functionality.
e522431d 612
7854b409 613To really understand this class, you will need to start with the
614L<Class::MOP::Class> documentation. This class can be understood as a
615set of additional features on top of the basic feature provided by
616that parent class.
6ba6d68c 617
d4b1449e 618=head1 INHERITANCE
619
620C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
621
c0e30cf5 622=head1 METHODS
623
624=over 4
625
70bb0f97 626=item B<< Moose::Meta::Class->initialize($package_name, %options) >>
590868a3 627
70bb0f97 628This overrides the parent's method in order to provide its own
629defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
630C<method_metaclass> options.
61bdd94f 631
70bb0f97 632These all default to the appropriate Moose class.
61bdd94f 633
70bb0f97 634=item B<< Moose::Meta::Class->create($package_name, %options) >>
17594769 635
70bb0f97 636This overrides the parent's method in order to accept a C<roles>
637option. This should be an array reference containing one more roles
638that the class does.
17594769 639
70bb0f97 640 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
17594769 641
70bb0f97 642=item B<< Moose::Meta::Class->create_anon_class >>
17594769 643
70bb0f97 644This overrides the parent's method to accept a C<roles> option, just
645as C<create> does.
5cf3dbcf 646
70bb0f97 647It also accepts a C<cache> option. If this is true, then the anonymous
648class will be cached based on its superclasses and roles. If an
649existing anonymous class in the cache has the same superclasses and
650roles, it will be reused.
ac2dc464 651
70bb0f97 652 my $metaclass = Moose::Meta::Class->create_anon_class(
653 superclasses => ['Foo'],
654 roles => [qw/Some Roles Go Here/],
655 cache => 1,
656 );
ac2dc464 657
70bb0f97 658=item B<< $metaclass->make_immutable(%options) >>
ac2dc464 659
70bb0f97 660This overrides the parent's method to add a few options. Specifically,
661it uses the Moose-specific constructor and destructor classes, and
662enables inlining the destructor.
8c9d74e7 663
70bb0f97 664Also, since Moose always inlines attributes, it sets the
665C<inline_accessors> option to false.
02a0fb52 666
70bb0f97 667=item B<< $metaclass->new_object(%params) >>
a15dff8d 668
70bb0f97 669This overrides the parent's method in order to add support for
670attribute triggers.
6ba6d68c 671
70bb0f97 672=item B<< $metaclass->add_override_method_modifier($name, $sub) >>
ef1d5f4b 673
70bb0f97 674This adds an C<override> method modifier to the package.
e9ec68d6 675
70bb0f97 676=item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
e9ec68d6 677
70bb0f97 678This adds an C<augment> method modifier to the package.
78cd1d3b 679
70bb0f97 680=item B<< $metaclass->calculate_all_roles >>
02a0fb52 681
70bb0f97 682This will return a unique array of C<Moose::Meta::Role> instances
683which are attached to this class.
78cd1d3b 684
70bb0f97 685=item B<< $metaclass->add_role($role) >>
02a0fb52 686
70bb0f97 687This takes a L<Moose::Meta::Role> object, and adds it to the class's
688list of roles. This I<does not> actually apply the role to the class.
2b14ac61 689
70bb0f97 690=item B<< $metaclass->does_role($role_name) >>
ef333f17 691
70bb0f97 692This returns a boolean indicating whether or not the class does the
693specified role. This tests both the class and its parents.
02a0fb52 694
70bb0f97 695=item B<< $metaclass->excludes_role($role_name) >>
ef333f17 696
70bb0f97 697A class excludes a role if it has already composed a role which
698excludes the named role. This tests both the class and its parents.
02a0fb52 699
70bb0f97 700=item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
ef333f17 701
70bb0f97 702This overrides the parent's method in order to allow the parameters to
703be provided as a hash reference.
02a0fb52 704
70bb0f97 705=item B<< $metaclass->constructor_class ($class_name) >>
d79e62fd 706
70bb0f97 707=item B<< $metaclass->destructor_class ($class_name) >>
e606ae5f 708
709These are the names of classes used when making a class
710immutable. These default to L<Moose::Meta::Method::Constructor> and
711L<Moose::Meta::Method::Destructor> respectively. These accessors are
712read-write, so you can use them to change the class name.
713
70bb0f97 714=item B<< $metaclass->error_class($class_name) >>
8b1d510f 715
70bb0f97 716The name of the class used to throw errors. This defaults to
8b1d510f 717L<Moose::Error::Default>, which generates an error with a stacktrace
718just like C<Carp::confess>.
719
70bb0f97 720=item B<< $metaclass->throw_error($message, %extra) >>
11c86f15 721
722Throws the error created by C<create_error> using C<raise_error>
723
c0e30cf5 724=back
725
726=head1 BUGS
727
ac2dc464 728All complex software has bugs lurking in it, and this module is no
c0e30cf5 729exception. If you find a bug please either email me, or add the bug
730to cpan-RT.
731
c0e30cf5 732=head1 AUTHOR
733
734Stevan Little E<lt>stevan@iinteractive.comE<gt>
735
736=head1 COPYRIGHT AND LICENSE
737
2840a3b2 738Copyright 2006-2009 by Infinity Interactive, Inc.
c0e30cf5 739
740L<http://www.iinteractive.com>
741
742This library is free software; you can redistribute it and/or modify
ac2dc464 743it under the same terms as Perl itself.
c0e30cf5 744
8a7a9c53 745=cut
1a563243 746