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