Changes to work with refactoring of immutable code in CMOP
[gitmo/Moose.git] / lib / Moose / Meta / Class.pm
CommitLineData
c0e30cf5 1
2package Moose::Meta::Class;
3
4use strict;
5use warnings;
6
0addec44 7use Class::MOP;
648e79ae 8
11c86f15 9use Carp ();
f8b6827f 10use List::Util qw( first );
8b1d510f 11use List::MoreUtils qw( any all uniq );
21f1e231 12use Scalar::Util 'weaken', 'blessed';
a15dff8d 13
4b2189ce 14our $VERSION = '0.72';
e606ae5f 15$VERSION = eval $VERSION;
d44714be 16our $AUTHORITY = 'cpan:STEVAN';
bc1e29b5 17
74862722 18use Moose::Meta::Method::Overridden;
3f9e4b0a 19use Moose::Meta::Method::Augmented;
bf6fa6b3 20use Moose::Error::Default;
8ee73eeb 21
c0e30cf5 22use base 'Class::MOP::Class';
23
598340d5 24__PACKAGE__->meta->add_attribute('roles' => (
ef333f17 25 reader => 'roles',
26 default => sub { [] }
27));
28
e606ae5f 29__PACKAGE__->meta->add_attribute('constructor_class' => (
30 accessor => 'constructor_class',
e0001338 31 default => 'Moose::Meta::Method::Constructor',
e606ae5f 32));
33
34__PACKAGE__->meta->add_attribute('destructor_class' => (
35 accessor => 'destructor_class',
e0001338 36 default => 'Moose::Meta::Method::Destructor',
e606ae5f 37));
38
11c86f15 39__PACKAGE__->meta->add_attribute('error_class' => (
bf6fa6b3 40 accessor => 'error_class',
41 default => 'Moose::Error::Default',
11c86f15 42));
43
44
590868a3 45sub initialize {
46 my $class = shift;
47 my $pkg = shift;
685f7e44 48 return Class::MOP::get_metaclass_by_name($pkg)
49 || $class->SUPER::initialize($pkg,
50 'attribute_metaclass' => 'Moose::Meta::Attribute',
51 'method_metaclass' => 'Moose::Meta::Method',
52 'instance_metaclass' => 'Moose::Meta::Instance',
53 @_
54 );
ac2dc464 55}
590868a3 56
61bdd94f 57sub create {
58 my ($self, $package_name, %options) = @_;
59
60 (ref $options{roles} eq 'ARRAY')
11c86f15 61 || $self->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
61bdd94f 62 if exists $options{roles};
310ba883 63 my $roles = delete $options{roles};
dd37a5be 64
61bdd94f 65 my $class = $self->SUPER::create($package_name, %options);
dd37a5be 66
310ba883 67 if ($roles) {
68 Moose::Util::apply_all_roles( $class, @$roles );
61bdd94f 69 }
70
71 return $class;
72}
73
2b72f3b4 74sub check_metaclass_compatibility {
75 my $self = shift;
76
77 if ( my @supers = $self->superclasses ) {
78 $self->_fix_metaclass_incompatibility(@supers);
79 }
80
81 $self->SUPER::check_metaclass_compatibility(@_);
82}
83
17594769 84my %ANON_CLASSES;
85
86sub create_anon_class {
87 my ($self, %options) = @_;
88
89 my $cache_ok = delete $options{cache};
17594769 90
91 # something like Super::Class|Super::Class::2=Role|Role::1
92 my $cache_key = join '=' => (
11aaed6c 93 join('|', @{$options{superclasses} || []}),
94 join('|', sort @{$options{roles} || []}),
17594769 95 );
96
6d5cbd2b 97 if ($cache_ok && defined $ANON_CLASSES{$cache_key}) {
17594769 98 return $ANON_CLASSES{$cache_key};
99 }
100
101 my $new_class = $self->SUPER::create_anon_class(%options);
102
6d5cbd2b 103 $ANON_CLASSES{$cache_key} = $new_class
104 if $cache_ok;
17594769 105
106 return $new_class;
107}
108
ef333f17 109sub add_role {
110 my ($self, $role) = @_;
111 (blessed($role) && $role->isa('Moose::Meta::Role'))
11c86f15 112 || $self->throw_error("Roles must be instances of Moose::Meta::Role", data => $role);
ef333f17 113 push @{$self->roles} => $role;
114}
115
b8aeb4dc 116sub calculate_all_roles {
117 my $self = shift;
118 my %seen;
119 grep { !$seen{$_->name}++ } map { $_->calculate_all_roles } @{ $self->roles };
120}
121
ef333f17 122sub does_role {
123 my ($self, $role_name) = @_;
124 (defined $role_name)
11c86f15 125 || $self->throw_error("You must supply a role name to look for");
9c429218 126 foreach my $class ($self->class_precedence_list) {
81c3738f 127 next unless $class->can('meta') && $class->meta->can('roles');
9c429218 128 foreach my $role (@{$class->meta->roles}) {
129 return 1 if $role->does_role($role_name);
130 }
ef333f17 131 }
132 return 0;
133}
134
d79e62fd 135sub excludes_role {
136 my ($self, $role_name) = @_;
137 (defined $role_name)
11c86f15 138 || $self->throw_error("You must supply a role name to look for");
ac2dc464 139 foreach my $class ($self->class_precedence_list) {
140 next unless $class->can('meta');
5cb193ed 141 # NOTE:
142 # in the pretty rare instance when a Moose metaclass
ac2dc464 143 # is itself extended with a role, this check needs to
5cb193ed 144 # be done since some items in the class_precedence_list
ac2dc464 145 # might in fact be Class::MOP based still.
146 next unless $class->meta->can('roles');
9c429218 147 foreach my $role (@{$class->meta->roles}) {
148 return 1 if $role->excludes_role($role_name);
149 }
d79e62fd 150 }
151 return 0;
152}
153
8c9d74e7 154sub new_object {
1308deb4 155 my $class = shift;
e606ae5f 156 my $params = @_ == 1 ? $_[0] : {@_};
1308deb4 157 my $self = $class->SUPER::new_object($params);
158
159 foreach my $attr ( $class->compute_all_applicable_attributes() ) {
160
161 next unless $attr->can('has_trigger') && $attr->has_trigger;
162
163 my $init_arg = $attr->init_arg;
164
165 next unless defined $init_arg;
166
167 next unless exists $params->{$init_arg};
168
169 $attr->trigger->(
170 $self,
171 (
172 $attr->should_coerce
173 ? $attr->get_read_method_ref->($self)
174 : $params->{$init_arg}
175 ),
176 $attr
177 );
8c9d74e7 178 }
1308deb4 179
ac2dc464 180 return $self;
8c9d74e7 181}
182
a15dff8d 183sub construct_instance {
e606ae5f 184 my $class = shift;
185 my $params = @_ == 1 ? $_[0] : {@_};
ddd0ec20 186 my $meta_instance = $class->get_meta_instance;
575db57d 187 # FIXME:
188 # the code below is almost certainly incorrect
6549b0d1 189 # but this is foreign inheritance, so we might
ac2dc464 190 # have to kludge it in the end.
e606ae5f 191 my $instance = $params->{'__INSTANCE__'} || $meta_instance->create_instance();
ac2dc464 192 foreach my $attr ($class->compute_all_applicable_attributes()) {
e606ae5f 193 $attr->initialize_instance_slot($meta_instance, $instance, $params);
a15dff8d 194 }
195 return $instance;
196}
197
093b12c2 198### ---------------------------------------------
199
a2eec5e7 200sub add_attribute {
201 my $self = shift;
e472c9a5 202 $self->SUPER::add_attribute(
203 (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
204 ? $_[0]
205 : $self->_process_attribute(@_))
206 );
a2eec5e7 207}
208
78cd1d3b 209sub add_override_method_modifier {
210 my ($self, $name, $method, $_super_package) = @_;
18c2ec0e 211
d05cd563 212 (!$self->has_method($name))
11c86f15 213 || $self->throw_error("Cannot add an override method if a local method is already present");
18c2ec0e 214
74862722 215 $self->add_method($name => Moose::Meta::Method::Overridden->new(
3f9e4b0a 216 method => $method,
217 class => $self,
218 package => $_super_package, # need this for roles
219 name => $name,
18c2ec0e 220 ));
78cd1d3b 221}
222
223sub add_augment_method_modifier {
ac2dc464 224 my ($self, $name, $method) = @_;
d05cd563 225 (!$self->has_method($name))
11c86f15 226 || $self->throw_error("Cannot add an augment method if a local method is already present");
3f9e4b0a 227
228 $self->add_method($name => Moose::Meta::Method::Augmented->new(
229 method => $method,
230 class => $self,
231 name => $name,
232 ));
78cd1d3b 233}
234
1341f10c 235## Private Utility methods ...
236
05d9eaf6 237sub _find_next_method_by_name_which_is_not_overridden {
238 my ($self, $name) = @_;
68efb014 239 foreach my $method ($self->find_all_methods_by_name($name)) {
ac2dc464 240 return $method->{code}
74862722 241 if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
05d9eaf6 242 }
243 return undef;
244}
245
41419b9e 246sub _fix_metaclass_incompatibility {
1341f10c 247 my ($self, @superclasses) = @_;
e606ae5f 248
1341f10c 249 foreach my $super (@superclasses) {
f8b6827f 250 next if $self->_superclass_meta_is_compatible($super);
e606ae5f 251
252 unless ( $self->is_pristine ) {
f8b6827f 253 $self->throw_error(
254 "Cannot attempt to reinitialize metaclass for "
255 . $self->name
256 . ", it isn't pristine" );
1341f10c 257 }
e606ae5f 258
0635500e 259 $self->_reconcile_with_superclass_meta($super);
f8b6827f 260 }
f8b6827f 261}
262
263sub _superclass_meta_is_compatible {
264 my ($self, $super) = @_;
265
266 my $super_meta = Class::MOP::Class->initialize($super)
267 or return 1;
268
269 next unless $super_meta->isa("Class::MOP::Class");
270
271 my $super_meta_name
272 = $super_meta->is_immutable
273 ? $super_meta->get_mutable_metaclass_name
274 : ref($super_meta);
275
276 return 1
277 if $self->isa($super_meta_name)
278 and
279 $self->instance_metaclass->isa( $super_meta->instance_metaclass );
280}
281
282# I don't want to have to type this >1 time
283my @MetaClassTypes =
8b1d510f 284 qw( attribute_metaclass method_metaclass instance_metaclass
285 constructor_class destructor_class error_class );
f8b6827f 286
287sub _reconcile_with_superclass_meta {
288 my ($self, $super) = @_;
289
290 my $super_meta = $super->meta;
291
dd37a5be 292 my $super_meta_name
f8b6827f 293 = $super_meta->is_immutable
294 ? $super_meta->get_mutable_metaclass_name
295 : ref($super_meta);
e606ae5f 296
f8b6827f 297 my $self_metaclass = ref $self;
298
299 # If neither of these is true we have a more serious
300 # incompatibility that we just cannot fix (yet?).
dd37a5be 301 if ( $super_meta_name->isa( ref $self )
f8b6827f 302 && all { $super_meta->$_->isa( $self->$_ ) } @MetaClassTypes ) {
0635500e 303 $self->_reinitialize_with($super_meta);
f8b6827f 304 }
305 elsif ( $self->_all_metaclasses_differ_by_roles_only($super_meta) ) {
0635500e 306 $self->_reconcile_role_differences($super_meta);
1341f10c 307 }
1341f10c 308}
309
f8b6827f 310sub _reinitialize_with {
311 my ( $self, $new_meta ) = @_;
312
0635500e 313 my $new_self = $new_meta->reinitialize(
f8b6827f 314 $self->name,
315 attribute_metaclass => $new_meta->attribute_metaclass,
316 method_metaclass => $new_meta->method_metaclass,
317 instance_metaclass => $new_meta->instance_metaclass,
318 );
319
8b1d510f 320 $new_self->$_( $new_meta->$_ )
321 for qw( constructor_class destructor_class error_class );
f8b6827f 322
0635500e 323 %$self = %$new_self;
324
325 bless $self, ref $new_self;
326
4c5fcc12 327 # We need to replace the cached metaclass instance or else when it
328 # goes out of scope Class::MOP::Class destroy's the namespace for
329 # the metaclass's class, causing much havoc.
0635500e 330 Class::MOP::store_metaclass_by_name( $self->name, $self );
4c5fcc12 331 Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class;
f8b6827f 332}
333
334# In the more complex case, we share a common ancestor with our
335# superclass's metaclass, but each metaclass (ours and the parent's)
336# has a different set of roles applied. We reconcile this by first
337# reinitializing into the parent class, and _then_ applying our own
338# roles.
339sub _all_metaclasses_differ_by_roles_only {
340 my ($self, $super_meta) = @_;
341
342 for my $pair (
343 [ ref $self, ref $super_meta ],
344 map { [ $self->$_, $super_meta->$_ ] } @MetaClassTypes
345 ) {
346
347 next if $pair->[0] eq $pair->[1];
348
349 my $self_meta_meta = Class::MOP::Class->initialize( $pair->[0] );
350 my $super_meta_meta = Class::MOP::Class->initialize( $pair->[1] );
351
352 my $common_ancestor
353 = _find_common_ancestor( $self_meta_meta, $super_meta_meta );
354
355 return unless $common_ancestor;
356
357 return
358 unless _is_role_only_subclass_of(
359 $self_meta_meta,
360 $common_ancestor,
361 )
362 && _is_role_only_subclass_of(
363 $super_meta_meta,
364 $common_ancestor,
365 );
366 }
367
368 return 1;
369}
370
371# This, and some other functions, could be called as methods, but
372# they're not for two reasons. One, we just end up ignoring the first
373# argument, because we can't call these directly on one of the real
374# arguments, because one of them could be a Class::MOP::Class object
375# and not a Moose::Meta::Class. Second, only a completely insane
376# person would attempt to subclass this stuff!
377sub _find_common_ancestor {
378 my ($meta1, $meta2) = @_;
379
380 # FIXME? This doesn't account for multiple inheritance (not sure
381 # if it needs to though). For example, is somewhere in $meta1's
382 # history it inherits from both ClassA and ClassB, and $meta
383 # inherits from ClassB & ClassA, does it matter? And what crazy
384 # fool would do that anyway?
385
386 my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
387
388 return first { $meta1_parents{$_} } $meta2->linearized_isa;
389}
390
391sub _is_role_only_subclass_of {
392 my ($meta, $ancestor) = @_;
393
394 return 1 if $meta->name eq $ancestor;
395
396 my @roles = _all_roles_until( $meta, $ancestor );
397
398 my %role_packages = map { $_->name => 1 } @roles;
399
400 my $ancestor_meta = Class::MOP::Class->initialize($ancestor);
401
402 my %shared_ancestors = map { $_ => 1 } $ancestor_meta->linearized_isa;
403
404 for my $method ( $meta->get_all_methods() ) {
405 next if $method->name eq 'meta';
406 next if $method->can('associated_attribute');
407
408 next
409 if $role_packages{ $method->original_package_name }
410 || $shared_ancestors{ $method->original_package_name };
411
412 return 0;
413 }
414
415 # FIXME - this really isn't right. Just because an attribute is
416 # defined in a role doesn't mean it isn't _also_ defined in the
417 # subclass.
418 for my $attr ( $meta->get_all_attributes ) {
419 next if $shared_ancestors{ $attr->associated_class->name };
420
421 next if any { $_->has_attribute( $attr->name ) } @roles;
422
423 return 0;
424 }
425
426 return 1;
427}
428
429sub _all_roles {
430 my $meta = shift;
431
432 return _all_roles_until($meta);
433}
434
435sub _all_roles_until {
436 my ($meta, $stop_at_class) = @_;
437
438 return unless $meta->can('calculate_all_roles');
439
440 my @roles = $meta->calculate_all_roles;
441
442 for my $class ( $meta->linearized_isa ) {
443 last if $stop_at_class && $stop_at_class eq $class;
444
445 my $meta = Class::MOP::Class->initialize($class);
446 last unless $meta->can('calculate_all_roles');
447
448 push @roles, $meta->calculate_all_roles;
449 }
450
8b1d510f 451 return uniq @roles;
f8b6827f 452}
453
454sub _reconcile_role_differences {
455 my ($self, $super_meta) = @_;
456
457 my $self_meta = $self->meta;
458
459 my %roles;
460
461 if ( my @roles = map { $_->name } _all_roles($self_meta) ) {
462 $roles{metaclass_roles} = \@roles;
463 }
464
465 for my $thing (@MetaClassTypes) {
466 my $name = $self->$thing();
467
468 my $thing_meta = Class::MOP::Class->initialize($name);
469
470 my @roles = map { $_->name } _all_roles($thing_meta)
471 or next;
472
473 $roles{ $thing . '_roles' } = \@roles;
474 }
475
2b72f3b4 476 $self->_reinitialize_with($super_meta);
f8b6827f 477
478 Moose::Util::MetaRole::apply_metaclass_roles(
479 for_class => $self->name,
480 %roles,
481 );
482
483 return $self;
484}
485
d7d8a8c7 486# NOTE:
d9bb6c63 487# this was crap anyway, see
488# Moose::Util::apply_all_roles
d7d8a8c7 489# instead
4498537c 490sub _apply_all_roles {
547dda77 491 Carp::croak 'DEPRECATED: use Moose::Util::apply_all_roles($meta, @roles) instead'
4498537c 492}
1341f10c 493
494sub _process_attribute {
a3738e5b 495 my ( $self, $name, @args ) = @_;
7e59b803 496
497 @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
d9bb6c63 498
f9b5f5f8 499 if (($name || '') =~ /^\+(.*)/) {
7e59b803 500 return $self->_process_inherited_attribute($1, @args);
1341f10c 501 }
502 else {
7e59b803 503 return $self->_process_new_attribute($name, @args);
504 }
505}
506
507sub _process_new_attribute {
508 my ( $self, $name, @args ) = @_;
7e59b803 509
d5c30e52 510 $self->attribute_metaclass->interpolate_class_and_new($name, @args);
1341f10c 511}
512
513sub _process_inherited_attribute {
514 my ($self, $attr_name, %options) = @_;
515 my $inherited_attr = $self->find_attribute_by_name($attr_name);
516 (defined $inherited_attr)
329c5dd4 517 || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
1341f10c 518 if ($inherited_attr->isa('Moose::Meta::Attribute')) {
d7d8a8c7 519 return $inherited_attr->clone_and_inherit_options(%options);
1341f10c 520 }
521 else {
522 # NOTE:
523 # kind of a kludge to handle Class::MOP::Attributes
d7d8a8c7 524 return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
ac2dc464 525 }
1341f10c 526}
527
5cf3dbcf 528## -------------------------------------------------
529
530use Moose::Meta::Method::Constructor;
1f779926 531use Moose::Meta::Method::Destructor;
5cf3dbcf 532
ac2dc464 533
959da293 534sub _default_immutable_transformer_options {
ac2dc464 535 my $self = shift;
959da293 536
537 my %options = $self->SUPER::_default_immutable_transformer_options;
538
539 # We need to copy the references as we do not want to alter the
540 # superclass's references.
541 $options{cannot_call} = [ @{ $options{cannot_call} }, 'add_role' ];
542 $options{memoize} = {
543 %{ $options{memoize} },
544 calculate_all_roles => 'ARRAY',
545 };
546
547 %options = (
548 %options,
549 constructor_class => $self->constructor_class,
550 destructor_class => $self->destructor_class,
551 inline_destructor => 1,
552
553 # Moose always does this when an attribute is created
554 inline_accessors => 0,
555 );
556
557 return %options
5cf3dbcf 558}
559
bf6fa6b3 560our $error_level;
11c86f15 561
562sub throw_error {
563 my ( $self, @args ) = @_;
bf6fa6b3 564 local $error_level = ($error_level || 0) + 1;
11c86f15 565 $self->raise_error($self->create_error(@args));
566}
567
568sub raise_error {
569 my ( $self, @args ) = @_;
570 die @args;
571}
572
573sub create_error {
574 my ( $self, @args ) = @_;
575
18748ad6 576 require Carp::Heavy;
577
bf6fa6b3 578 local $error_level = ($error_level || 0 ) + 1;
18748ad6 579
11c86f15 580 if ( @args % 2 == 1 ) {
581 unshift @args, "message";
582 }
583
fcab1742 584 my %args = ( metaclass => $self, last_error => $@, @args );
11c86f15 585
bf6fa6b3 586 $args{depth} += $error_level;
11c86f15 587
bf6fa6b3 588 my $class = ref $self ? $self->error_class : "Moose::Error::Default";
11c86f15 589
a810a01f 590 Class::MOP::load_class($class);
591
11c86f15 592 $class->new(
bf6fa6b3 593 Carp::caller_info($args{depth}),
594 %args
11c86f15 595 );
596}
597
c0e30cf5 5981;
599
600__END__
601
602=pod
603
604=head1 NAME
605
e522431d 606Moose::Meta::Class - The Moose metaclass
c0e30cf5 607
c0e30cf5 608=head1 DESCRIPTION
609
ac2dc464 610This is a subclass of L<Class::MOP::Class> with Moose specific
e522431d 611extensions.
612
ac2dc464 613For the most part, the only time you will ever encounter an
614instance of this class is if you are doing some serious deep
615introspection. To really understand this class, you need to refer
6ba6d68c 616to the L<Class::MOP::Class> documentation.
617
c0e30cf5 618=head1 METHODS
619
620=over 4
621
590868a3 622=item B<initialize>
623
61bdd94f 624=item B<create>
625
17594769 626Overrides original to accept a list of roles to apply to
61bdd94f 627the created class.
628
17594769 629 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
630
631=item B<create_anon_class>
632
633Overrides original to support roles and caching.
634
635 my $metaclass = Moose::Meta::Class->create_anon_class(
636 superclasses => ['Foo'],
637 roles => [qw/Some Roles Go Here/],
638 cache => 1,
639 );
640
5cf3dbcf 641=item B<make_immutable>
642
ac2dc464 643Override original to add default options for inlining destructor
644and altering the Constructor metaclass.
645
646=item B<create_immutable_transformer>
647
648Override original to lock C<add_role> and memoize C<calculate_all_roles>
649
8c9d74e7 650=item B<new_object>
651
02a0fb52 652We override this method to support the C<trigger> attribute option.
653
a15dff8d 654=item B<construct_instance>
655
ac2dc464 656This provides some Moose specific extensions to this method, you
657almost never call this method directly unless you really know what
658you are doing.
6ba6d68c 659
660This method makes sure to handle the moose weak-ref, type-constraint
ac2dc464 661and type coercion features.
ef1d5f4b 662
093b12c2 663=item B<get_method_map>
e9ec68d6 664
ac2dc464 665This accommodates Moose::Meta::Role::Method instances, which are
666aliased, instead of added, but still need to be counted as valid
e9ec68d6 667methods.
668
78cd1d3b 669=item B<add_override_method_modifier ($name, $method)>
670
ac2dc464 671This will create an C<override> method modifier for you, and install
02a0fb52 672it in the package.
673
78cd1d3b 674=item B<add_augment_method_modifier ($name, $method)>
675
ac2dc464 676This will create an C<augment> method modifier for you, and install
02a0fb52 677it in the package.
678
2b14ac61 679=item B<calculate_all_roles>
680
ef333f17 681=item B<roles>
682
ac2dc464 683This will return an array of C<Moose::Meta::Role> instances which are
02a0fb52 684attached to this class.
685
ef333f17 686=item B<add_role ($role)>
687
ac2dc464 688This takes an instance of C<Moose::Meta::Role> in C<$role>, and adds it
02a0fb52 689to the list of associated roles.
690
ef333f17 691=item B<does_role ($role_name)>
692
ac2dc464 693This will test if this class C<does> a given C<$role_name>. It will
694not only check it's local roles, but ask them as well in order to
02a0fb52 695cascade down the role hierarchy.
696
d79e62fd 697=item B<excludes_role ($role_name)>
698
ac2dc464 699This will test if this class C<excludes> a given C<$role_name>. It will
700not only check it's local roles, but ask them as well in order to
d79e62fd 701cascade down the role hierarchy.
702
9e93dd19 703=item B<add_attribute ($attr_name, %params|$params)>
4e848edb 704
9e93dd19 705This method does the same thing as L<Class::MOP::Class::add_attribute>, but adds
706support for taking the C<$params> as a HASH ref.
ac1ef2f9 707
e606ae5f 708=item B<constructor_class ($class_name)>
709
710=item B<destructor_class ($class_name)>
711
712These are the names of classes used when making a class
713immutable. These default to L<Moose::Meta::Method::Constructor> and
714L<Moose::Meta::Method::Destructor> respectively. These accessors are
715read-write, so you can use them to change the class name.
716
8b1d510f 717=item B<error_class ($class_name)>
718
719The name of the class used to throw errors. This default to
720L<Moose::Error::Default>, which generates an error with a stacktrace
721just like C<Carp::confess>.
722
4fb87686 723=item B<check_metaclass_compatibility>
724
725Moose overrides this method from C<Class::MOP::Class> and attempts to
726fix some incompatibilities before doing the check.
727
11c86f15 728=item B<throw_error $message, %extra>
729
730Throws the error created by C<create_error> using C<raise_error>
731
732=item B<create_error $message, %extra>
733
734Creates an error message or object.
735
736The default behavior is C<create_error_confess>.
737
738If C<error_class> is set uses C<create_error_object>. Otherwise uses
739C<error_builder> (a code reference or variant name), and calls the appropriate
740C<create_error_$builder> method.
741
742=item B<error_builder $builder_name>
743
744Get or set the error builder. Defaults to C<confess>.
745
746=item B<error_class $class_name>
747
50e9d6a5 748Get or set the error class. This defaults to L<Moose::Error::Default>.
11c86f15 749
750=item B<create_error_confess %args>
751
752Creates an error using L<Carp/longmess>
753
754=item B<create_error_croak %args>
755
756Creates an error using L<Carp/shortmess>
757
758=item B<create_error_object %args>
759
760Calls C<new> on the C<class> parameter in C<%args>. Usable with C<error_class>
761to support custom error objects for your meta class.
762
763=item B<raise_error $error>
764
765Dies with an error object or string.
766
c0e30cf5 767=back
768
769=head1 BUGS
770
ac2dc464 771All complex software has bugs lurking in it, and this module is no
c0e30cf5 772exception. If you find a bug please either email me, or add the bug
773to cpan-RT.
774
c0e30cf5 775=head1 AUTHOR
776
777Stevan Little E<lt>stevan@iinteractive.comE<gt>
778
779=head1 COPYRIGHT AND LICENSE
780
2840a3b2 781Copyright 2006-2009 by Infinity Interactive, Inc.
c0e30cf5 782
783L<http://www.iinteractive.com>
784
785This library is free software; you can redistribute it and/or modify
ac2dc464 786it under the same terms as Perl itself.
c0e30cf5 787
8a7a9c53 788=cut
1a563243 789