1431810e5bcb394a0fa5d15a073051fd701863d4
[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 List::Util qw( first );
11 use List::MoreUtils qw( any all uniq first_index );
12 use Scalar::Util 'weaken', 'blessed';
13
14 our $VERSION   = '0.89_01';
15 $VERSION = eval $VERSION;
16 our $AUTHORITY = 'cpan:STEVAN';
17
18 use Moose::Meta::Method::Overridden;
19 use Moose::Meta::Method::Augmented;
20 use Moose::Error::Default;
21 use Moose::Meta::Class::Immutable::Trait;
22 use Moose::Meta::Method::Constructor;
23 use Moose::Meta::Method::Destructor;
24
25 use base 'Class::MOP::Class';
26
27 __PACKAGE__->meta->add_attribute('roles' => (
28     reader  => 'roles',
29     default => sub { [] }
30 ));
31
32 __PACKAGE__->meta->add_attribute('role_applications' => (
33     reader  => '_get_role_applications',
34     default => sub { [] }
35 ));
36
37 __PACKAGE__->meta->add_attribute(
38     Class::MOP::Attribute->new('immutable_trait' => (
39         accessor => "immutable_trait",
40         default  => 'Moose::Meta::Class::Immutable::Trait',
41     ))
42 );
43
44 __PACKAGE__->meta->add_attribute('constructor_class' => (
45     accessor => 'constructor_class',
46     default  => 'Moose::Meta::Method::Constructor',
47 ));
48
49 __PACKAGE__->meta->add_attribute('destructor_class' => (
50     accessor => 'destructor_class',
51     default  => 'Moose::Meta::Method::Destructor',
52 ));
53
54 __PACKAGE__->meta->add_attribute('error_class' => (
55     accessor => 'error_class',
56     default  => 'Moose::Error::Default',
57 ));
58
59 sub initialize {
60     my $class = shift;
61     my $pkg   = shift;
62     return Class::MOP::get_metaclass_by_name($pkg)
63         || $class->SUPER::initialize($pkg,
64                 'attribute_metaclass' => 'Moose::Meta::Attribute',
65                 'method_metaclass'    => 'Moose::Meta::Method',
66                 'instance_metaclass'  => 'Moose::Meta::Instance',
67                 @_
68             );
69 }
70
71 sub _immutable_options {
72     my ( $self, @args ) = @_;
73
74     $self->SUPER::_immutable_options(
75         allow_mutable_ancestors => 0,
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     # something like Super::Class|Super::Class::2=Role|Role::1
120     my $cache_key = join '=' => (
121         join('|', @{$options{superclasses} || []}),
122         join('|', sort @{$options{roles}   || []}),
123     );
124
125     if ($cache_ok && defined $ANON_CLASSES{$cache_key}) {
126         return $ANON_CLASSES{$cache_key};
127     }
128
129     my $new_class = $self->SUPER::create_anon_class(%options);
130
131     $ANON_CLASSES{$cache_key} = $new_class
132         if $cache_ok;
133
134     return $new_class;
135 }
136
137 sub add_role {
138     my ($self, $role) = @_;
139     (blessed($role) && $role->isa('Moose::Meta::Role'))
140         || $self->throw_error("Roles must be instances of Moose::Meta::Role", data => $role);
141     push @{$self->roles} => $role;
142 }
143
144 sub make_immutable {
145     my $self = shift;
146     my %args = @_;
147
148     # we do this for metaclasses way too often to do this check for them
149     if ( !$args{allow_mutable_ancestors}
150       && !$self->name->isa('Class::MOP::Object') ) {
151         my @superclasses = grep { $_ ne 'Moose::Object' && $_ ne $self->name }
152             $self->linearized_isa;
153
154         for my $superclass (@superclasses) {
155             my $meta = Class::MOP::class_of($superclass);
156
157             next unless $meta && $meta->isa('Moose::Meta::Class');
158             next unless $meta->is_mutable;
159             # This can happen when a base class role is applied via
160             # Moose::Util::MetaRole::apply_base_class_roles. The parent is an
161             # anon class and is still mutable, but that's okay.
162             next if $meta->is_anon_class;
163
164             Carp::cluck( "Calling make_immutable on "
165                     . $self->name
166                     . ", which has a mutable ancestor ($superclass)" );
167             last;
168         }
169     }
170
171     $self->SUPER::make_immutable(@_);
172 }
173
174 sub role_applications {
175     my ($self) = @_;
176
177     return @{$self->_get_role_applications};
178 }
179
180 sub add_role_application {
181     my ($self, $application) = @_;
182     (blessed($application) && $application->isa('Moose::Meta::Role::Application::ToClass'))
183         || $self->throw_error("Role applications must be instances of Moose::Meta::Role::Application::ToClass", data => $application);
184     push @{$self->_get_role_applications} => $application;
185 }
186
187 sub calculate_all_roles {
188     my $self = shift;
189     my %seen;
190     grep { !$seen{$_->name}++ } map { $_->calculate_all_roles } @{ $self->roles };
191 }
192
193 sub does_role {
194     my ($self, $role_name) = @_;
195
196     (defined $role_name)
197         || $self->throw_error("You must supply a role name to look for");
198
199     foreach my $class ($self->class_precedence_list) {
200         my $meta = Class::MOP::class_of($class);
201         # when a Moose metaclass is itself extended with a role,
202         # this check needs to be done since some items in the
203         # class_precedence_list might in fact be Class::MOP
204         # based still.
205         next unless $meta && $meta->can('roles');
206         foreach my $role (@{$meta->roles}) {
207             return 1 if $role->does_role($role_name);
208         }
209     }
210     return 0;
211 }
212
213 sub excludes_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->excludes_role($role_name);
228         }
229     }
230     return 0;
231 }
232
233 sub new_object {
234     my $class  = shift;
235     my $params = @_ == 1 ? $_[0] : {@_};
236     my $self   = $class->SUPER::new_object($params);
237
238     foreach my $attr ( $class->get_all_attributes() ) {
239
240         next unless $attr->can('has_trigger') && $attr->has_trigger;
241
242         my $init_arg = $attr->init_arg;
243
244         next unless defined $init_arg;
245
246         next unless exists $params->{$init_arg};
247
248         $attr->trigger->(
249             $self,
250             (
251                   $attr->should_coerce
252                 ? $attr->get_read_method_ref->($self)
253                 : $params->{$init_arg}
254             ),
255         );
256     }
257
258     return $self;
259 }
260
261 sub superclasses {
262     my $self = shift;
263     my @supers = @_;
264     foreach my $super (@supers) {
265         Class::MOP::load_class($super);
266         my $meta = Class::MOP::class_of($super);
267         $self->throw_error("You cannot inherit from a Moose Role ($super)")
268             if $meta && $meta->isa('Moose::Meta::Role')
269     }
270     return $self->SUPER::superclasses(@supers);
271 }
272
273 ### ---------------------------------------------
274
275 sub add_attribute {
276     my $self = shift;
277     my $attr =
278         (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
279             ? $_[0]
280             : $self->_process_attribute(@_));
281     $self->SUPER::add_attribute($attr);
282     # it may be a Class::MOP::Attribute, theoretically, which doesn't have
283     # 'bare' and doesn't implement this method
284     if ($attr->can('_check_associated_methods')) {
285         $attr->_check_associated_methods;
286     }
287     return $attr;
288 }
289
290 sub add_override_method_modifier {
291     my ($self, $name, $method, $_super_package) = @_;
292
293     (!$self->has_method($name))
294         || $self->throw_error("Cannot add an override method if a local method is already present");
295
296     $self->add_method($name => Moose::Meta::Method::Overridden->new(
297         method  => $method,
298         class   => $self,
299         package => $_super_package, # need this for roles
300         name    => $name,
301     ));
302 }
303
304 sub add_augment_method_modifier {
305     my ($self, $name, $method) = @_;
306     (!$self->has_method($name))
307         || $self->throw_error("Cannot add an augment method if a local method is already present");
308
309     $self->add_method($name => Moose::Meta::Method::Augmented->new(
310         method  => $method,
311         class   => $self,
312         name    => $name,
313     ));
314 }
315
316 ## Private Utility methods ...
317
318 sub _find_next_method_by_name_which_is_not_overridden {
319     my ($self, $name) = @_;
320     foreach my $method ($self->find_all_methods_by_name($name)) {
321         return $method->{code}
322             if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
323     }
324     return undef;
325 }
326
327 sub _fix_metaclass_incompatibility {
328     my ($self, @superclasses) = @_;
329
330     foreach my $super (@superclasses) {
331         my $meta = Class::MOP::Class->initialize($super);
332
333         my @all_supers = $meta->linearized_isa;
334         shift @all_supers;
335
336         my @super_metas_to_fix = ($meta);
337
338         # We need to check & fix the immediate superclass. If its @ISA
339         # contains a class without a metaclass instance, followed by a
340         # class _with_ a metaclass instance, init a metaclass instance
341         # for classes without one and fix compat up to and including
342         # the class which was already initialized.
343         my $idx = first_index { Class::MOP::class_of($_) } @all_supers;
344
345         push @super_metas_to_fix,
346             map { Class::MOP::Class->initialize($_) } @all_supers[ 0 .. $idx ]
347             if $idx >= 0;
348
349         foreach my $super_meta (@super_metas_to_fix) {
350             $self->_fix_one_incompatible_metaclass($super_meta);
351         }
352     }
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 =item B<< $metaclass->make_immutable(%options) >>
729
730 This overrides the parent's method to add a few options. Specifically,
731 it uses the Moose-specific constructor and destructor classes, and
732 enables inlining the destructor.
733
734 Also, since Moose always inlines attributes, it sets the
735 C<inline_accessors> option to false.
736
737 It also accepts the additional C<allow_mutable_ancestors> option, to
738 silence the warning you get when trying to make a class with mutable
739 ancestors immutable.
740
741 =item B<< $metaclass->new_object(%params) >>
742
743 This overrides the parent's method in order to add support for
744 attribute triggers.
745
746 =item B<< $metaclass->add_override_method_modifier($name, $sub) >>
747
748 This adds an C<override> method modifier to the package.
749
750 =item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
751
752 This adds an C<augment> method modifier to the package.
753
754 =item B<< $metaclass->calculate_all_roles >>
755
756 This will return a unique array of C<Moose::Meta::Role> instances
757 which are attached to this class.
758
759 =item B<< $metaclass->add_role($role) >>
760
761 This takes a L<Moose::Meta::Role> object, and adds it to the class's
762 list of roles. This I<does not> actually apply the role to the class.
763
764 =item B<< $metaclass->role_applications >>
765
766 Returns a list of L<Moose::Meta::Role::Application::ToClass>
767 objects, which contain the arguments to role application.
768
769 =item B<< $metaclass->add_role_application($application) >>
770
771 This takes a L<Moose::Meta::Role::Application::ToClass> object, and
772 adds it to the class's list of role applications. This I<does not>
773 actually apply any role to the class; it is only for tracking role
774 applications.
775
776 =item B<< $metaclass->does_role($role_name) >>
777
778 This returns a boolean indicating whether or not the class does the
779 specified role. This tests both the class and its parents.
780
781 =item B<< $metaclass->excludes_role($role_name) >>
782
783 A class excludes a role if it has already composed a role which
784 excludes the named role. This tests both the class and its parents.
785
786 =item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
787
788 This overrides the parent's method in order to allow the parameters to
789 be provided as a hash reference.
790
791 =item B<< $metaclass->constructor_class ($class_name) >>
792
793 =item B<< $metaclass->destructor_class ($class_name) >>
794
795 These are the names of classes used when making a class
796 immutable. These default to L<Moose::Meta::Method::Constructor> and
797 L<Moose::Meta::Method::Destructor> respectively. These accessors are
798 read-write, so you can use them to change the class name.
799
800 =item B<< $metaclass->error_class($class_name) >>
801
802 The name of the class used to throw errors. This defaults to
803 L<Moose::Error::Default>, which generates an error with a stacktrace
804 just like C<Carp::confess>.
805
806 =item B<< $metaclass->throw_error($message, %extra) >>
807
808 Throws the error created by C<create_error> using C<raise_error>
809
810 =back
811
812 =head1 BUGS
813
814 All complex software has bugs lurking in it, and this module is no
815 exception. If you find a bug please either email me, or add the bug
816 to cpan-RT.
817
818 =head1 AUTHOR
819
820 Stevan Little E<lt>stevan@iinteractive.comE<gt>
821
822 =head1 COPYRIGHT AND LICENSE
823
824 Copyright 2006-2009 by Infinity Interactive, Inc.
825
826 L<http://www.iinteractive.com>
827
828 This library is free software; you can redistribute it and/or modify
829 it under the same terms as Perl itself.
830
831 =cut
832