Fix typo.
[gitmo/Moose.git] / lib / Moose / Meta / Class.pm
1
2 package Moose::Meta::Class;
3
4 use strict;
5 use warnings;
6
7 use Class::MOP;
8
9 use Carp ();
10 use Data::OptList;
11 use List::Util qw( first );
12 use List::MoreUtils qw( any all uniq first_index );
13 use Scalar::Util 'weaken', 'blessed';
14
15 our $VERSION   = '1.03';
16 $VERSION = eval $VERSION;
17 our $AUTHORITY = 'cpan:STEVAN';
18
19 use Moose::Meta::Method::Overridden;
20 use Moose::Meta::Method::Augmented;
21 use Moose::Error::Default;
22 use Moose::Meta::Class::Immutable::Trait;
23 use Moose::Meta::Method::Constructor;
24 use Moose::Meta::Method::Destructor;
25
26 use base 'Class::MOP::Class';
27
28 __PACKAGE__->meta->add_attribute('roles' => (
29     reader  => 'roles',
30     default => sub { [] }
31 ));
32
33 __PACKAGE__->meta->add_attribute('role_applications' => (
34     reader  => '_get_role_applications',
35     default => sub { [] }
36 ));
37
38 __PACKAGE__->meta->add_attribute(
39     Class::MOP::Attribute->new('immutable_trait' => (
40         accessor => "immutable_trait",
41         default  => 'Moose::Meta::Class::Immutable::Trait',
42     ))
43 );
44
45 __PACKAGE__->meta->add_attribute('constructor_class' => (
46     accessor => 'constructor_class',
47     default  => 'Moose::Meta::Method::Constructor',
48 ));
49
50 __PACKAGE__->meta->add_attribute('destructor_class' => (
51     accessor => 'destructor_class',
52     default  => 'Moose::Meta::Method::Destructor',
53 ));
54
55 __PACKAGE__->meta->add_attribute('error_class' => (
56     accessor => 'error_class',
57     default  => 'Moose::Error::Default',
58 ));
59
60 sub initialize {
61     my $class = shift;
62     my $pkg   = shift;
63     return Class::MOP::get_metaclass_by_name($pkg)
64         || $class->SUPER::initialize($pkg,
65                 'attribute_metaclass' => 'Moose::Meta::Attribute',
66                 'method_metaclass'    => 'Moose::Meta::Method',
67                 'instance_metaclass'  => 'Moose::Meta::Instance',
68                 @_
69             );
70 }
71
72 sub _immutable_options {
73     my ( $self, @args ) = @_;
74
75     $self->SUPER::_immutable_options(
76         inline_destructor => 1,
77
78         # Moose always does this when an attribute is created
79         inline_accessors => 0,
80
81         @args,
82     );
83 }
84
85 sub create {
86     my ($self, $package_name, %options) = @_;
87
88     (ref $options{roles} eq 'ARRAY')
89         || $self->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
90             if exists $options{roles};
91     my $roles = delete $options{roles};
92
93     my $class = $self->SUPER::create($package_name, %options);
94
95     if ($roles) {
96         Moose::Util::apply_all_roles( $class, @$roles );
97     }
98
99     return $class;
100 }
101
102 sub _check_metaclass_compatibility {
103     my $self = shift;
104
105     if ( my @supers = $self->superclasses ) {
106         $self->_fix_metaclass_incompatibility(@supers);
107     }
108
109     $self->SUPER::_check_metaclass_compatibility(@_);
110 }
111
112 my %ANON_CLASSES;
113
114 sub create_anon_class {
115     my ($self, %options) = @_;
116
117     my $cache_ok = delete $options{cache};
118
119     my $cache_key
120         = _anon_cache_key( $options{superclasses}, $options{roles} );
121
122     if ($cache_ok && defined $ANON_CLASSES{$cache_key}) {
123         return $ANON_CLASSES{$cache_key};
124     }
125
126     my $new_class = $self->SUPER::create_anon_class(%options);
127
128     $ANON_CLASSES{$cache_key} = $new_class
129         if $cache_ok;
130
131     return $new_class;
132 }
133
134 sub _anon_cache_key {
135     # Makes something like Super::Class|Super::Class::2=Role|Role::1
136     return join '=' => (
137         join( '|', @{ $_[0]      || [] } ),
138         join( '|', sort @{ $_[1] || [] } ),
139     );
140 }
141
142 sub reinitialize {
143     my $self = shift;
144     my $pkg  = shift;
145
146     my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg);
147
148     my $cache_key;
149
150     my %existing_classes;
151     if ($meta) {
152         %existing_classes = map { $_ => $meta->$_() } qw(
153             attribute_metaclass
154             method_metaclass
155             wrapped_method_metaclass
156             instance_metaclass
157             constructor_class
158             destructor_class
159             error_class
160         );
161
162         $cache_key = _anon_cache_key(
163             [ $meta->superclasses ],
164             [ map { $_->name } @{ $meta->roles } ],
165         ) if $meta->is_anon_class;
166     }
167
168     my $new_meta = $self->SUPER::reinitialize(
169         $pkg,
170         %existing_classes,
171         @_,
172     );
173
174     return $new_meta unless defined $cache_key;
175
176     my $new_cache_key = _anon_cache_key(
177         [ $meta->superclasses ],
178         [ map { $_->name } @{ $meta->roles } ],
179     );
180
181     delete $ANON_CLASSES{$cache_key};
182     $ANON_CLASSES{$new_cache_key} = $new_meta;
183
184     return $new_meta;
185 }
186
187 sub add_role {
188     my ($self, $role) = @_;
189     (blessed($role) && $role->isa('Moose::Meta::Role'))
190         || $self->throw_error("Roles must be instances of Moose::Meta::Role", data => $role);
191     push @{$self->roles} => $role;
192 }
193
194 sub role_applications {
195     my ($self) = @_;
196
197     return @{$self->_get_role_applications};
198 }
199
200 sub add_role_application {
201     my ($self, $application) = @_;
202     (blessed($application) && $application->isa('Moose::Meta::Role::Application::ToClass'))
203         || $self->throw_error("Role applications must be instances of Moose::Meta::Role::Application::ToClass", data => $application);
204     push @{$self->_get_role_applications} => $application;
205 }
206
207 sub calculate_all_roles {
208     my $self = shift;
209     my %seen;
210     grep { !$seen{$_->name}++ } map { $_->calculate_all_roles } @{ $self->roles };
211 }
212
213 sub does_role {
214     my ($self, $role_name) = @_;
215
216     (defined $role_name)
217         || $self->throw_error("You must supply a role name to look for");
218
219     foreach my $class ($self->class_precedence_list) {
220         my $meta = Class::MOP::class_of($class);
221         # when a Moose metaclass is itself extended with a role,
222         # this check needs to be done since some items in the
223         # class_precedence_list might in fact be Class::MOP
224         # based still.
225         next unless $meta && $meta->can('roles');
226         foreach my $role (@{$meta->roles}) {
227             return 1 if $role->does_role($role_name);
228         }
229     }
230     return 0;
231 }
232
233 sub excludes_role {
234     my ($self, $role_name) = @_;
235
236     (defined $role_name)
237         || $self->throw_error("You must supply a role name to look for");
238
239     foreach my $class ($self->class_precedence_list) {
240         my $meta = Class::MOP::class_of($class);
241         # when a Moose metaclass is itself extended with a role,
242         # this check needs to be done since some items in the
243         # class_precedence_list might in fact be Class::MOP
244         # based still.
245         next unless $meta && $meta->can('roles');
246         foreach my $role (@{$meta->roles}) {
247             return 1 if $role->excludes_role($role_name);
248         }
249     }
250     return 0;
251 }
252
253 sub new_object {
254     my $class  = shift;
255     my $params = @_ == 1 ? $_[0] : {@_};
256     my $self   = $class->SUPER::new_object($params);
257
258     foreach my $attr ( $class->get_all_attributes() ) {
259
260         next unless $attr->can('has_trigger') && $attr->has_trigger;
261
262         my $init_arg = $attr->init_arg;
263
264         next unless defined $init_arg;
265
266         next unless exists $params->{$init_arg};
267
268         $attr->trigger->(
269             $self,
270             (
271                   $attr->should_coerce
272                 ? $attr->get_read_method_ref->($self)
273                 : $params->{$init_arg}
274             ),
275         );
276     }
277
278     return $self;
279 }
280
281 sub superclasses {
282     my $self = shift;
283     my $supers = Data::OptList::mkopt(\@_);
284     foreach my $super (@{ $supers }) {
285         my ($name, $opts) = @{ $super };
286         Class::MOP::load_class($name, $opts);
287         my $meta = Class::MOP::class_of($name);
288         $self->throw_error("You cannot inherit from a Moose Role ($name)")
289             if $meta && $meta->isa('Moose::Meta::Role')
290     }
291     return $self->SUPER::superclasses(map { $_->[0] } @{ $supers });
292 }
293
294 ### ---------------------------------------------
295
296 sub add_attribute {
297     my $self = shift;
298     my $attr =
299         (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
300             ? $_[0]
301             : $self->_process_attribute(@_));
302     $self->SUPER::add_attribute($attr);
303     # it may be a Class::MOP::Attribute, theoretically, which doesn't have
304     # 'bare' and doesn't implement this method
305     if ($attr->can('_check_associated_methods')) {
306         $attr->_check_associated_methods;
307     }
308     return $attr;
309 }
310
311 sub add_override_method_modifier {
312     my ($self, $name, $method, $_super_package) = @_;
313
314     (!$self->has_method($name))
315         || $self->throw_error("Cannot add an override method if a local method is already present");
316
317     $self->add_method($name => Moose::Meta::Method::Overridden->new(
318         method  => $method,
319         class   => $self,
320         package => $_super_package, # need this for roles
321         name    => $name,
322     ));
323 }
324
325 sub add_augment_method_modifier {
326     my ($self, $name, $method) = @_;
327     (!$self->has_method($name))
328         || $self->throw_error("Cannot add an augment method if a local method is already present");
329
330     $self->add_method($name => Moose::Meta::Method::Augmented->new(
331         method  => $method,
332         class   => $self,
333         name    => $name,
334     ));
335 }
336
337 ## Private Utility methods ...
338
339 sub _find_next_method_by_name_which_is_not_overridden {
340     my ($self, $name) = @_;
341     foreach my $method ($self->find_all_methods_by_name($name)) {
342         return $method->{code}
343             if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
344     }
345     return undef;
346 }
347
348 sub _fix_metaclass_incompatibility {
349     my ($self, @superclasses) = @_;
350
351     $self->_fix_one_incompatible_metaclass($_)
352         for map { Moose::Meta::Class->initialize($_) } @superclasses;
353 }
354
355 sub _fix_one_incompatible_metaclass {
356     my ($self, $meta) = @_;
357
358     return if $self->_superclass_meta_is_compatible($meta);
359
360     unless ( $self->is_pristine ) {
361         $self->throw_error(
362               "Cannot attempt to reinitialize metaclass for "
363             . $self->name
364             . ", it isn't pristine" );
365     }
366
367     $self->_reconcile_with_superclass_meta($meta);
368 }
369
370 sub _superclass_meta_is_compatible {
371     my ($self, $super_meta) = @_;
372
373     next unless $super_meta->isa("Class::MOP::Class");
374
375     my $super_meta_name
376         = $super_meta->is_immutable
377         ? $super_meta->_get_mutable_metaclass_name
378         : ref($super_meta);
379
380     return 1
381         if $self->isa($super_meta_name)
382             and
383            $self->instance_metaclass->isa( $super_meta->instance_metaclass );
384 }
385
386 # I don't want to have to type this >1 time
387 my @MetaClassTypes =
388     qw( attribute_metaclass
389         method_metaclass
390         wrapped_method_metaclass
391         instance_metaclass
392         constructor_class
393         destructor_class
394         error_class );
395
396 sub _reconcile_with_superclass_meta {
397     my ($self, $super_meta) = @_;
398
399     my $super_meta_name
400         = $super_meta->is_immutable
401         ? $super_meta->_get_mutable_metaclass_name
402         : ref($super_meta);
403
404     my $self_metaclass = ref $self;
405
406     # If neither of these is true we have a more serious
407     # incompatibility that we just cannot fix (yet?).
408     if ( $super_meta_name->isa( ref $self )
409         && all { $super_meta->$_->isa( $self->$_ ) } @MetaClassTypes ) {
410         $self->_reinitialize_with($super_meta);
411     }
412     elsif ( $self->_all_metaclasses_differ_by_roles_only($super_meta) ) {
413         $self->_reconcile_role_differences($super_meta);
414     }
415 }
416
417 sub _reinitialize_with {
418     my ( $self, $new_meta ) = @_;
419
420     my $new_self = $new_meta->reinitialize(
421         $self->name,
422         attribute_metaclass => $new_meta->attribute_metaclass,
423         method_metaclass    => $new_meta->method_metaclass,
424         instance_metaclass  => $new_meta->instance_metaclass,
425     );
426
427     $new_self->$_( $new_meta->$_ )
428         for qw( constructor_class destructor_class error_class );
429
430     %$self = %$new_self;
431
432     bless $self, ref $new_self;
433
434     # We need to replace the cached metaclass instance or else when it
435     # goes out of scope Class::MOP::Class destroy's the namespace for
436     # the metaclass's class, causing much havoc.
437     Class::MOP::store_metaclass_by_name( $self->name, $self );
438     Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class;
439 }
440
441 # In the more complex case, we share a common ancestor with our
442 # superclass's metaclass, but each metaclass (ours and the parent's)
443 # has a different set of roles applied. We reconcile this by first
444 # reinitializing into the parent class, and _then_ applying our own
445 # roles.
446 sub _all_metaclasses_differ_by_roles_only {
447     my ($self, $super_meta) = @_;
448
449     for my $pair (
450         [ ref $self, ref $super_meta ],
451         map { [ $self->$_, $super_meta->$_ ] } @MetaClassTypes
452         ) {
453
454         next if $pair->[0] eq $pair->[1];
455
456         my $self_meta_meta  = Class::MOP::Class->initialize( $pair->[0] );
457         my $super_meta_meta = Class::MOP::Class->initialize( $pair->[1] );
458
459         my $common_ancestor
460             = _find_common_ancestor( $self_meta_meta, $super_meta_meta );
461
462         return unless $common_ancestor;
463
464         return
465             unless _is_role_only_subclass_of(
466             $self_meta_meta,
467             $common_ancestor,
468             )
469             && _is_role_only_subclass_of(
470             $super_meta_meta,
471             $common_ancestor,
472             );
473     }
474
475     return 1;
476 }
477
478 # This, and some other functions, could be called as methods, but
479 # they're not for two reasons. One, we just end up ignoring the first
480 # argument, because we can't call these directly on one of the real
481 # arguments, because one of them could be a Class::MOP::Class object
482 # and not a Moose::Meta::Class. Second, only a completely insane
483 # person would attempt to subclass this stuff!
484 sub _find_common_ancestor {
485     my ($meta1, $meta2) = @_;
486
487     # FIXME? This doesn't account for multiple inheritance (not sure
488     # if it needs to though). For example, is somewhere in $meta1's
489     # history it inherits from both ClassA and ClassB, and $meta2
490     # inherits from ClassB & ClassA, does it matter? And what crazy
491     # fool would do that anyway?
492
493     my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
494
495     return first { $meta1_parents{$_} } $meta2->linearized_isa;
496 }
497
498 sub _is_role_only_subclass_of {
499     my ($meta, $ancestor) = @_;
500
501     return 1 if $meta->name eq $ancestor;
502
503     my @roles = _all_roles_until( $meta, $ancestor );
504
505     my %role_packages = map { $_->name => 1 } @roles;
506
507     my $ancestor_meta = Class::MOP::Class->initialize($ancestor);
508
509     my %shared_ancestors = map { $_ => 1 } $ancestor_meta->linearized_isa;
510
511     for my $method ( $meta->get_all_methods() ) {
512         next if $method->name eq 'meta';
513         next if $method->can('associated_attribute');
514
515         next
516             if $role_packages{ $method->original_package_name }
517                 || $shared_ancestors{ $method->original_package_name };
518
519         return 0;
520     }
521
522     # FIXME - this really isn't right. Just because an attribute is
523     # defined in a role doesn't mean it isn't _also_ defined in the
524     # subclass.
525     for my $attr ( $meta->get_all_attributes ) {
526         next if $shared_ancestors{ $attr->associated_class->name };
527
528         next if any { $_->has_attribute( $attr->name ) } @roles;
529
530         return 0;
531     }
532
533     return 1;
534 }
535
536 sub _all_roles {
537     my $meta = shift;
538
539     return _all_roles_until($meta);
540 }
541
542 sub _all_roles_until {
543     my ($meta, $stop_at_class) = @_;
544
545     return unless $meta->can('calculate_all_roles');
546
547     my @roles = $meta->calculate_all_roles;
548
549     for my $class ( $meta->linearized_isa ) {
550         last if $stop_at_class && $stop_at_class eq $class;
551
552         my $meta = Class::MOP::Class->initialize($class);
553         last unless $meta->can('calculate_all_roles');
554
555         push @roles, $meta->calculate_all_roles;
556     }
557
558     return uniq @roles;
559 }
560
561 sub _reconcile_role_differences {
562     my ($self, $super_meta) = @_;
563
564     my $self_meta = Class::MOP::class_of($self);
565
566     my %roles;
567
568     if ( my @roles = map { $_->name } _all_roles($self_meta) ) {
569         $roles{metaclass_roles} = \@roles;
570     }
571
572     for my $thing (@MetaClassTypes) {
573         my $name = $self->$thing();
574
575         my $thing_meta = Class::MOP::Class->initialize($name);
576
577         my @roles = map { $_->name } _all_roles($thing_meta)
578             or next;
579
580         $roles{ $thing . '_roles' } = \@roles;
581     }
582
583     $self->_reinitialize_with($super_meta);
584
585     Moose::Util::MetaRole::apply_metaclass_roles(
586         for_class => $self->name,
587         %roles,
588     );
589
590     return $self;
591 }
592
593 sub _process_attribute {
594     my ( $self, $name, @args ) = @_;
595
596     @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
597
598     if (($name || '') =~ /^\+(.*)/) {
599         return $self->_process_inherited_attribute($1, @args);
600     }
601     else {
602         return $self->_process_new_attribute($name, @args);
603     }
604 }
605
606 sub _process_new_attribute {
607     my ( $self, $name, @args ) = @_;
608
609     $self->attribute_metaclass->interpolate_class_and_new($name, @args);
610 }
611
612 sub _process_inherited_attribute {
613     my ($self, $attr_name, %options) = @_;
614     my $inherited_attr = $self->find_attribute_by_name($attr_name);
615     (defined $inherited_attr)
616         || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
617     if ($inherited_attr->isa('Moose::Meta::Attribute')) {
618         return $inherited_attr->clone_and_inherit_options(%options);
619     }
620     else {
621         # NOTE:
622         # kind of a kludge to handle Class::MOP::Attributes
623         return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
624     }
625 }
626
627 ## -------------------------------------------------
628
629 our $error_level;
630
631 sub throw_error {
632     my ( $self, @args ) = @_;
633     local $error_level = ($error_level || 0) + 1;
634     $self->raise_error($self->create_error(@args));
635 }
636
637 sub raise_error {
638     my ( $self, @args ) = @_;
639     die @args;
640 }
641
642 sub create_error {
643     my ( $self, @args ) = @_;
644
645     require Carp::Heavy;
646
647     local $error_level = ($error_level || 0 ) + 1;
648
649     if ( @args % 2 == 1 ) {
650         unshift @args, "message";
651     }
652
653     my %args = ( metaclass => $self, last_error => $@, @args );
654
655     $args{depth} += $error_level;
656
657     my $class = ref $self ? $self->error_class : "Moose::Error::Default";
658
659     Class::MOP::load_class($class);
660
661     $class->new(
662         Carp::caller_info($args{depth}),
663         %args
664     );
665 }
666
667 1;
668
669 __END__
670
671 =pod
672
673 =head1 NAME
674
675 Moose::Meta::Class - The Moose metaclass
676
677 =head1 DESCRIPTION
678
679 This class is a subclass of L<Class::MOP::Class> that provides
680 additional Moose-specific functionality.
681
682 To really understand this class, you will need to start with the
683 L<Class::MOP::Class> documentation. This class can be understood as a
684 set of additional features on top of the basic feature provided by
685 that parent class.
686
687 =head1 INHERITANCE
688
689 C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
690
691 =head1 METHODS
692
693 =over 4
694
695 =item B<< Moose::Meta::Class->initialize($package_name, %options) >>
696
697 This overrides the parent's method in order to provide its own
698 defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
699 C<method_metaclass> options.
700
701 These all default to the appropriate Moose class.
702
703 =item B<< Moose::Meta::Class->create($package_name, %options) >>
704
705 This overrides the parent's method in order to accept a C<roles>
706 option. This should be an array reference containing roles
707 that the class does, each optionally followed by a hashref of options
708 (C<-excludes> and C<-alias>).
709
710   my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
711
712 =item B<< Moose::Meta::Class->create_anon_class >>
713
714 This overrides the parent's method to accept a C<roles> option, just
715 as C<create> does.
716
717 It also accepts a C<cache> option. If this is true, then the anonymous
718 class will be cached based on its superclasses and roles. If an
719 existing anonymous class in the cache has the same superclasses and
720 roles, it will be reused.
721
722   my $metaclass = Moose::Meta::Class->create_anon_class(
723       superclasses => ['Foo'],
724       roles        => [qw/Some Roles Go Here/],
725       cache        => 1,
726   );
727
728 Each entry in both the C<superclasses> and the C<roles> option can be
729 followed by a hash reference with arguments. The C<superclasses>
730 option can be supplied with a L<-version|Class::MOP/Class Loading
731 Options> option that ensures the loaded superclass satisfies the
732 required version. The C<role> option also takes the C<-version> as an
733 argument, but the option hash reference can also contain any other
734 role relevant values like exclusions or parameterized role arguments.
735
736 =item B<< $metaclass->make_immutable(%options) >>
737
738 This overrides the parent's method to add a few options. Specifically,
739 it uses the Moose-specific constructor and destructor classes, and
740 enables inlining the destructor.
741
742 Also, since Moose always inlines attributes, it sets the
743 C<inline_accessors> option to false.
744
745 =item B<< $metaclass->new_object(%params) >>
746
747 This overrides the parent's method in order to add support for
748 attribute triggers.
749
750 =item B<< $metaclass->superclasses(@superclasses) >>
751
752 This is the accessor allowing you to read or change the parents of
753 the class.
754
755 Each superclass can be followed by a hash reference containing a
756 L<-version|Class::MOP/Class Loading Options> value. If the version
757 requirement is not satisfied an error will be thrown.
758
759 =item B<< $metaclass->add_override_method_modifier($name, $sub) >>
760
761 This adds an C<override> method modifier to the package.
762
763 =item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
764
765 This adds an C<augment> method modifier to the package.
766
767 =item B<< $metaclass->calculate_all_roles >>
768
769 This will return a unique array of C<Moose::Meta::Role> instances
770 which are attached to this class.
771
772 =item B<< $metaclass->add_role($role) >>
773
774 This takes a L<Moose::Meta::Role> object, and adds it to the class's
775 list of roles. This I<does not> actually apply the role to the class.
776
777 =item B<< $metaclass->role_applications >>
778
779 Returns a list of L<Moose::Meta::Role::Application::ToClass>
780 objects, which contain the arguments to role application.
781
782 =item B<< $metaclass->add_role_application($application) >>
783
784 This takes a L<Moose::Meta::Role::Application::ToClass> object, and
785 adds it to the class's list of role applications. This I<does not>
786 actually apply any role to the class; it is only for tracking role
787 applications.
788
789 =item B<< $metaclass->does_role($role) >>
790
791 This returns a boolean indicating whether or not the class does the specified
792 role. The role provided can be either a role name or a L<Moose::Meta::Role>
793 object. This tests both the class and its parents.
794
795 =item B<< $metaclass->excludes_role($role_name) >>
796
797 A class excludes a role if it has already composed a role which
798 excludes the named role. This tests both the class and its parents.
799
800 =item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
801
802 This overrides the parent's method in order to allow the parameters to
803 be provided as a hash reference.
804
805 =item B<< $metaclass->constructor_class ($class_name) >>
806
807 =item B<< $metaclass->destructor_class ($class_name) >>
808
809 These are the names of classes used when making a class
810 immutable. These default to L<Moose::Meta::Method::Constructor> and
811 L<Moose::Meta::Method::Destructor> respectively. These accessors are
812 read-write, so you can use them to change the class name.
813
814 =item B<< $metaclass->error_class($class_name) >>
815
816 The name of the class used to throw errors. This defaults to
817 L<Moose::Error::Default>, which generates an error with a stacktrace
818 just like C<Carp::confess>.
819
820 =item B<< $metaclass->throw_error($message, %extra) >>
821
822 Throws the error created by C<create_error> using C<raise_error>
823
824 =back
825
826 =head1 BUGS
827
828 See L<Moose/BUGS> for details on reporting bugs.
829
830 =head1 AUTHOR
831
832 Stevan Little E<lt>stevan@iinteractive.comE<gt>
833
834 =head1 COPYRIGHT AND LICENSE
835
836 Copyright 2006-2010 by Infinity Interactive, Inc.
837
838 L<http://www.iinteractive.com>
839
840 This library is free software; you can redistribute it and/or modify
841 it under the same terms as Perl itself.
842
843 =cut
844