Version 1.04
[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.04';
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 ($class, $package_name, %options) = @_;
87
88     (ref $options{roles} eq 'ARRAY')
89         || $class->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 $new_meta = $class->SUPER::create($package_name, %options);
94
95     if ($roles) {
96         Moose::Util::apply_all_roles( $new_meta, @$roles );
97     }
98
99     return $new_meta;
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 $self   = shift;
255     my $params = @_ == 1 ? $_[0] : {@_};
256     my $object = $self->SUPER::new_object($params);
257
258     foreach my $attr ( $self->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             $object,
270             (
271                   $attr->should_coerce
272                 ? $attr->get_read_method_ref->($object)
273                 : $params->{$init_arg}
274             ),
275         );
276     }
277
278     $object->BUILDALL($params) if $object->can('BUILDALL');
279
280     return $object;
281 }
282
283 sub superclasses {
284     my $self = shift;
285     my $supers = Data::OptList::mkopt(\@_);
286     foreach my $super (@{ $supers }) {
287         my ($name, $opts) = @{ $super };
288         Class::MOP::load_class($name, $opts);
289         my $meta = Class::MOP::class_of($name);
290         $self->throw_error("You cannot inherit from a Moose Role ($name)")
291             if $meta && $meta->isa('Moose::Meta::Role')
292     }
293     return $self->SUPER::superclasses(map { $_->[0] } @{ $supers });
294 }
295
296 ### ---------------------------------------------
297
298 sub add_attribute {
299     my $self = shift;
300     my $attr =
301         (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
302             ? $_[0]
303             : $self->_process_attribute(@_));
304     $self->SUPER::add_attribute($attr);
305     # it may be a Class::MOP::Attribute, theoretically, which doesn't have
306     # 'bare' and doesn't implement this method
307     if ($attr->can('_check_associated_methods')) {
308         $attr->_check_associated_methods;
309     }
310     return $attr;
311 }
312
313 sub add_override_method_modifier {
314     my ($self, $name, $method, $_super_package) = @_;
315
316     (!$self->has_method($name))
317         || $self->throw_error("Cannot add an override method if a local method is already present");
318
319     $self->add_method($name => Moose::Meta::Method::Overridden->new(
320         method  => $method,
321         class   => $self,
322         package => $_super_package, # need this for roles
323         name    => $name,
324     ));
325 }
326
327 sub add_augment_method_modifier {
328     my ($self, $name, $method) = @_;
329     (!$self->has_method($name))
330         || $self->throw_error("Cannot add an augment method if a local method is already present");
331
332     $self->add_method($name => Moose::Meta::Method::Augmented->new(
333         method  => $method,
334         class   => $self,
335         name    => $name,
336     ));
337 }
338
339 ## Private Utility methods ...
340
341 sub _find_next_method_by_name_which_is_not_overridden {
342     my ($self, $name) = @_;
343     foreach my $method ($self->find_all_methods_by_name($name)) {
344         return $method->{code}
345             if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
346     }
347     return undef;
348 }
349
350 sub _fix_metaclass_incompatibility {
351     my ($self, @superclasses) = @_;
352
353     $self->_fix_one_incompatible_metaclass($_)
354         for map { Moose::Meta::Class->initialize($_) } @superclasses;
355 }
356
357 sub _fix_one_incompatible_metaclass {
358     my ($self, $meta) = @_;
359
360     return if $self->_superclass_meta_is_compatible($meta);
361
362     unless ( $self->is_pristine ) {
363         $self->throw_error(
364               "Cannot attempt to reinitialize metaclass for "
365             . $self->name
366             . ", it isn't pristine" );
367     }
368
369     $self->_reconcile_with_superclass_meta($meta);
370 }
371
372 sub _superclass_meta_is_compatible {
373     my ($self, $super_meta) = @_;
374
375     next unless $super_meta->isa("Class::MOP::Class");
376
377     my $super_meta_name
378         = $super_meta->is_immutable
379         ? $super_meta->_get_mutable_metaclass_name
380         : ref($super_meta);
381
382     return 1
383         if $self->isa($super_meta_name)
384             and
385            $self->instance_metaclass->isa( $super_meta->instance_metaclass );
386 }
387
388 # I don't want to have to type this >1 time
389 my @MetaClassTypes =
390     qw( attribute_metaclass
391         method_metaclass
392         wrapped_method_metaclass
393         instance_metaclass
394         constructor_class
395         destructor_class
396         error_class );
397
398 sub _reconcile_with_superclass_meta {
399     my ($self, $super_meta) = @_;
400
401     my $super_meta_name
402         = $super_meta->is_immutable
403         ? $super_meta->_get_mutable_metaclass_name
404         : ref($super_meta);
405
406     my $self_metaclass = ref $self;
407
408     # If neither of these is true we have a more serious
409     # incompatibility that we just cannot fix (yet?).
410     if ( $super_meta_name->isa( ref $self )
411         && all { $super_meta->$_->isa( $self->$_ ) } @MetaClassTypes ) {
412         $self->_reinitialize_with($super_meta);
413     }
414     elsif ( $self->_all_metaclasses_differ_by_roles_only($super_meta) ) {
415         $self->_reconcile_role_differences($super_meta);
416     }
417 }
418
419 sub _reinitialize_with {
420     my ( $self, $new_meta ) = @_;
421
422     my $new_self = $new_meta->reinitialize(
423         $self->name,
424         attribute_metaclass => $new_meta->attribute_metaclass,
425         method_metaclass    => $new_meta->method_metaclass,
426         instance_metaclass  => $new_meta->instance_metaclass,
427     );
428
429     $new_self->$_( $new_meta->$_ )
430         for qw( constructor_class destructor_class error_class );
431
432     %$self = %$new_self;
433
434     bless $self, ref $new_self;
435
436     # We need to replace the cached metaclass instance or else when it
437     # goes out of scope Class::MOP::Class destroy's the namespace for
438     # the metaclass's class, causing much havoc.
439     Class::MOP::store_metaclass_by_name( $self->name, $self );
440     Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class;
441 }
442
443 # In the more complex case, we share a common ancestor with our
444 # superclass's metaclass, but each metaclass (ours and the parent's)
445 # has a different set of roles applied. We reconcile this by first
446 # reinitializing into the parent class, and _then_ applying our own
447 # roles.
448 sub _all_metaclasses_differ_by_roles_only {
449     my ($self, $super_meta) = @_;
450
451     for my $pair (
452         [ ref $self, ref $super_meta ],
453         map { [ $self->$_, $super_meta->$_ ] } @MetaClassTypes
454         ) {
455
456         next if $pair->[0] eq $pair->[1];
457
458         my $self_meta_meta  = Class::MOP::Class->initialize( $pair->[0] );
459         my $super_meta_meta = Class::MOP::Class->initialize( $pair->[1] );
460
461         my $common_ancestor
462             = _find_common_ancestor( $self_meta_meta, $super_meta_meta );
463
464         return unless $common_ancestor;
465
466         return
467             unless _is_role_only_subclass_of(
468             $self_meta_meta,
469             $common_ancestor,
470             )
471             && _is_role_only_subclass_of(
472             $super_meta_meta,
473             $common_ancestor,
474             );
475     }
476
477     return 1;
478 }
479
480 # This, and some other functions, could be called as methods, but
481 # they're not for two reasons. One, we just end up ignoring the first
482 # argument, because we can't call these directly on one of the real
483 # arguments, because one of them could be a Class::MOP::Class object
484 # and not a Moose::Meta::Class. Second, only a completely insane
485 # person would attempt to subclass this stuff!
486 sub _find_common_ancestor {
487     my ($meta1, $meta2) = @_;
488
489     # FIXME? This doesn't account for multiple inheritance (not sure
490     # if it needs to though). For example, is somewhere in $meta1's
491     # history it inherits from both ClassA and ClassB, and $meta2
492     # inherits from ClassB & ClassA, does it matter? And what crazy
493     # fool would do that anyway?
494
495     my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
496
497     return first { $meta1_parents{$_} } $meta2->linearized_isa;
498 }
499
500 sub _is_role_only_subclass_of {
501     my ($meta, $ancestor) = @_;
502
503     return 1 if $meta->name eq $ancestor;
504
505     my @roles = _all_roles_until( $meta, $ancestor );
506
507     my %role_packages = map { $_->name => 1 } @roles;
508
509     my $ancestor_meta = Class::MOP::Class->initialize($ancestor);
510
511     my %shared_ancestors = map { $_ => 1 } $ancestor_meta->linearized_isa;
512
513     for my $method ( $meta->get_all_methods() ) {
514         next if $method->name eq 'meta';
515         next if $method->can('associated_attribute');
516
517         next
518             if $role_packages{ $method->original_package_name }
519                 || $shared_ancestors{ $method->original_package_name };
520
521         return 0;
522     }
523
524     # FIXME - this really isn't right. Just because an attribute is
525     # defined in a role doesn't mean it isn't _also_ defined in the
526     # subclass.
527     for my $attr ( $meta->get_all_attributes ) {
528         next if $shared_ancestors{ $attr->associated_class->name };
529
530         next if any { $_->has_attribute( $attr->name ) } @roles;
531
532         return 0;
533     }
534
535     return 1;
536 }
537
538 sub _all_roles {
539     my $meta = shift;
540
541     return _all_roles_until($meta);
542 }
543
544 sub _all_roles_until {
545     my ($meta, $stop_at_class) = @_;
546
547     return unless $meta->can('calculate_all_roles');
548
549     my @roles = $meta->calculate_all_roles;
550
551     for my $class ( $meta->linearized_isa ) {
552         last if $stop_at_class && $stop_at_class eq $class;
553
554         my $meta = Class::MOP::Class->initialize($class);
555         last unless $meta->can('calculate_all_roles');
556
557         push @roles, $meta->calculate_all_roles;
558     }
559
560     return uniq @roles;
561 }
562
563 sub _reconcile_role_differences {
564     my ($self, $super_meta) = @_;
565
566     my $self_meta = Class::MOP::class_of($self);
567
568     my %roles;
569
570     if ( my @roles = map { $_->name } _all_roles($self_meta) ) {
571         $roles{metaclass_roles} = \@roles;
572     }
573
574     for my $thing (@MetaClassTypes) {
575         my $name = $self->$thing();
576
577         my $thing_meta = Class::MOP::Class->initialize($name);
578
579         my @roles = map { $_->name } _all_roles($thing_meta)
580             or next;
581
582         $roles{ $thing . '_roles' } = \@roles;
583     }
584
585     $self->_reinitialize_with($super_meta);
586
587     Moose::Util::MetaRole::apply_metaclass_roles(
588         for_class => $self->name,
589         %roles,
590     );
591
592     return $self;
593 }
594
595 sub _process_attribute {
596     my ( $self, $name, @args ) = @_;
597
598     @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
599
600     if (($name || '') =~ /^\+(.*)/) {
601         return $self->_process_inherited_attribute($1, @args);
602     }
603     else {
604         return $self->_process_new_attribute($name, @args);
605     }
606 }
607
608 sub _process_new_attribute {
609     my ( $self, $name, @args ) = @_;
610
611     $self->attribute_metaclass->interpolate_class_and_new($name, @args);
612 }
613
614 sub _process_inherited_attribute {
615     my ($self, $attr_name, %options) = @_;
616     my $inherited_attr = $self->find_attribute_by_name($attr_name);
617     (defined $inherited_attr)
618         || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
619     if ($inherited_attr->isa('Moose::Meta::Attribute')) {
620         return $inherited_attr->clone_and_inherit_options(%options);
621     }
622     else {
623         # NOTE:
624         # kind of a kludge to handle Class::MOP::Attributes
625         return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
626     }
627 }
628
629 ## -------------------------------------------------
630
631 our $error_level;
632
633 sub throw_error {
634     my ( $self, @args ) = @_;
635     local $error_level = ($error_level || 0) + 1;
636     $self->raise_error($self->create_error(@args));
637 }
638
639 sub raise_error {
640     my ( $self, @args ) = @_;
641     die @args;
642 }
643
644 sub create_error {
645     my ( $self, @args ) = @_;
646
647     require Carp::Heavy;
648
649     local $error_level = ($error_level || 0 ) + 1;
650
651     if ( @args % 2 == 1 ) {
652         unshift @args, "message";
653     }
654
655     my %args = ( metaclass => $self, last_error => $@, @args );
656
657     $args{depth} += $error_level;
658
659     my $class = ref $self ? $self->error_class : "Moose::Error::Default";
660
661     Class::MOP::load_class($class);
662
663     $class->new(
664         Carp::caller_info($args{depth}),
665         %args
666     );
667 }
668
669 1;
670
671 __END__
672
673 =pod
674
675 =head1 NAME
676
677 Moose::Meta::Class - The Moose metaclass
678
679 =head1 DESCRIPTION
680
681 This class is a subclass of L<Class::MOP::Class> that provides
682 additional Moose-specific functionality.
683
684 To really understand this class, you will need to start with the
685 L<Class::MOP::Class> documentation. This class can be understood as a
686 set of additional features on top of the basic feature provided by
687 that parent class.
688
689 =head1 INHERITANCE
690
691 C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
692
693 =head1 METHODS
694
695 =over 4
696
697 =item B<< Moose::Meta::Class->initialize($package_name, %options) >>
698
699 This overrides the parent's method in order to provide its own
700 defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
701 C<method_metaclass> options.
702
703 These all default to the appropriate Moose class.
704
705 =item B<< Moose::Meta::Class->create($package_name, %options) >>
706
707 This overrides the parent's method in order to accept a C<roles>
708 option. This should be an array reference containing roles
709 that the class does, each optionally followed by a hashref of options
710 (C<-excludes> and C<-alias>).
711
712   my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
713
714 =item B<< Moose::Meta::Class->create_anon_class >>
715
716 This overrides the parent's method to accept a C<roles> option, just
717 as C<create> does.
718
719 It also accepts a C<cache> option. If this is true, then the anonymous
720 class will be cached based on its superclasses and roles. If an
721 existing anonymous class in the cache has the same superclasses and
722 roles, it will be reused.
723
724   my $metaclass = Moose::Meta::Class->create_anon_class(
725       superclasses => ['Foo'],
726       roles        => [qw/Some Roles Go Here/],
727       cache        => 1,
728   );
729
730 Each entry in both the C<superclasses> and the C<roles> option can be
731 followed by a hash reference with arguments. The C<superclasses>
732 option can be supplied with a L<-version|Class::MOP/Class Loading
733 Options> option that ensures the loaded superclass satisfies the
734 required version. The C<role> option also takes the C<-version> as an
735 argument, but the option hash reference can also contain any other
736 role relevant values like exclusions or parameterized role arguments.
737
738 =item B<< $metaclass->make_immutable(%options) >>
739
740 This overrides the parent's method to add a few options. Specifically,
741 it uses the Moose-specific constructor and destructor classes, and
742 enables inlining the destructor.
743
744 Also, since Moose always inlines attributes, it sets the
745 C<inline_accessors> option to false.
746
747 =item B<< $metaclass->new_object(%params) >>
748
749 This overrides the parent's method in order to add support for
750 attribute triggers.
751
752 =item B<< $metaclass->superclasses(@superclasses) >>
753
754 This is the accessor allowing you to read or change the parents of
755 the class.
756
757 Each superclass can be followed by a hash reference containing a
758 L<-version|Class::MOP/Class Loading Options> value. If the version
759 requirement is not satisfied an error will be thrown.
760
761 =item B<< $metaclass->add_override_method_modifier($name, $sub) >>
762
763 This adds an C<override> method modifier to the package.
764
765 =item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
766
767 This adds an C<augment> method modifier to the package.
768
769 =item B<< $metaclass->calculate_all_roles >>
770
771 This will return a unique array of C<Moose::Meta::Role> instances
772 which are attached to this class.
773
774 =item B<< $metaclass->add_role($role) >>
775
776 This takes a L<Moose::Meta::Role> object, and adds it to the class's
777 list of roles. This I<does not> actually apply the role to the class.
778
779 =item B<< $metaclass->role_applications >>
780
781 Returns a list of L<Moose::Meta::Role::Application::ToClass>
782 objects, which contain the arguments to role application.
783
784 =item B<< $metaclass->add_role_application($application) >>
785
786 This takes a L<Moose::Meta::Role::Application::ToClass> object, and
787 adds it to the class's list of role applications. This I<does not>
788 actually apply any role to the class; it is only for tracking role
789 applications.
790
791 =item B<< $metaclass->does_role($role) >>
792
793 This returns a boolean indicating whether or not the class does the specified
794 role. The role provided can be either a role name or a L<Moose::Meta::Role>
795 object. This tests both the class and its parents.
796
797 =item B<< $metaclass->excludes_role($role_name) >>
798
799 A class excludes a role if it has already composed a role which
800 excludes the named role. This tests both the class and its parents.
801
802 =item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
803
804 This overrides the parent's method in order to allow the parameters to
805 be provided as a hash reference.
806
807 =item B<< $metaclass->constructor_class($class_name) >>
808
809 =item B<< $metaclass->destructor_class($class_name) >>
810
811 These are the names of classes used when making a class
812 immutable. These default to L<Moose::Meta::Method::Constructor> and
813 L<Moose::Meta::Method::Destructor> respectively. These accessors are
814 read-write, so you can use them to change the class name.
815
816 =item B<< $metaclass->error_class($class_name) >>
817
818 The name of the class used to throw errors. This defaults to
819 L<Moose::Error::Default>, which generates an error with a stacktrace
820 just like C<Carp::confess>.
821
822 =item B<< $metaclass->throw_error($message, %extra) >>
823
824 Throws the error created by C<create_error> using C<raise_error>
825
826 =back
827
828 =head1 BUGS
829
830 See L<Moose/BUGS> for details on reporting bugs.
831
832 =head1 AUTHOR
833
834 Stevan Little E<lt>stevan@iinteractive.comE<gt>
835
836 =head1 COPYRIGHT AND LICENSE
837
838 Copyright 2006-2010 by Infinity Interactive, Inc.
839
840 L<http://www.iinteractive.com>
841
842 This library is free software; you can redistribute it and/or modify
843 it under the same terms as Perl itself.
844
845 =cut
846