make variable naming more clear, and fix some bugs that this uncovered
[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 ();
2e7f6cf4 10use Data::OptList;
f8b6827f 11use List::Util qw( first );
349cda54 12use List::MoreUtils qw( any all uniq first_index );
21f1e231 13use Scalar::Util 'weaken', 'blessed';
a15dff8d 14
40290d18 15our $VERSION = '1.04';
e606ae5f 16$VERSION = eval $VERSION;
d44714be 17our $AUTHORITY = 'cpan:STEVAN';
bc1e29b5 18
74862722 19use Moose::Meta::Method::Overridden;
3f9e4b0a 20use Moose::Meta::Method::Augmented;
77f14411 21use Moose::Error::Default;
0fa70d03 22use Moose::Meta::Class::Immutable::Trait;
23use Moose::Meta::Method::Constructor;
24use Moose::Meta::Method::Destructor;
8ee73eeb 25
c0e30cf5 26use base 'Class::MOP::Class';
27
598340d5 28__PACKAGE__->meta->add_attribute('roles' => (
ef333f17 29 reader => 'roles',
30 default => sub { [] }
31));
32
a9b63d79 33__PACKAGE__->meta->add_attribute('role_applications' => (
639f9a1a 34 reader => '_get_role_applications',
a9b63d79 35 default => sub { [] }
36));
37
0fa70d03 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
e606ae5f 45__PACKAGE__->meta->add_attribute('constructor_class' => (
46 accessor => 'constructor_class',
e0001338 47 default => 'Moose::Meta::Method::Constructor',
e606ae5f 48));
49
50__PACKAGE__->meta->add_attribute('destructor_class' => (
51 accessor => 'destructor_class',
e0001338 52 default => 'Moose::Meta::Method::Destructor',
e606ae5f 53));
54
11c86f15 55__PACKAGE__->meta->add_attribute('error_class' => (
bf6fa6b3 56 accessor => 'error_class',
57 default => 'Moose::Error::Default',
11c86f15 58));
59
590868a3 60sub initialize {
61 my $class = shift;
62 my $pkg = shift;
d03bd989 63 return Class::MOP::get_metaclass_by_name($pkg)
685f7e44 64 || $class->SUPER::initialize($pkg,
65 'attribute_metaclass' => 'Moose::Meta::Attribute',
66 'method_metaclass' => 'Moose::Meta::Method',
67 'instance_metaclass' => 'Moose::Meta::Instance',
68 @_
d03bd989 69 );
ac2dc464 70}
590868a3 71
0fa70d03 72sub _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
61bdd94f 85sub create {
7d4035ae 86 my ($class, $package_name, %options) = @_;
d03bd989 87
61bdd94f 88 (ref $options{roles} eq 'ARRAY')
7d4035ae 89 || $class->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
61bdd94f 90 if exists $options{roles};
310ba883 91 my $roles = delete $options{roles};
dd37a5be 92
7d4035ae 93 my $new_meta = $class->SUPER::create($package_name, %options);
dd37a5be 94
310ba883 95 if ($roles) {
7d4035ae 96 Moose::Util::apply_all_roles( $new_meta, @$roles );
61bdd94f 97 }
d03bd989 98
7d4035ae 99 return $new_meta;
61bdd94f 100}
101
17594769 102my %ANON_CLASSES;
103
104sub create_anon_class {
105 my ($self, %options) = @_;
106
107 my $cache_ok = delete $options{cache};
d03bd989 108
cf600c83 109 my $cache_key
110 = _anon_cache_key( $options{superclasses}, $options{roles} );
d03bd989 111
6d5cbd2b 112 if ($cache_ok && defined $ANON_CLASSES{$cache_key}) {
17594769 113 return $ANON_CLASSES{$cache_key};
114 }
d03bd989 115
17594769 116 my $new_class = $self->SUPER::create_anon_class(%options);
117
6d5cbd2b 118 $ANON_CLASSES{$cache_key} = $new_class
119 if $cache_ok;
17594769 120
121 return $new_class;
122}
123
cf600c83 124sub _anon_cache_key {
125 # Makes something like Super::Class|Super::Class::2=Role|Role::1
126 return join '=' => (
127 join( '|', @{ $_[0] || [] } ),
128 join( '|', sort @{ $_[1] || [] } ),
129 );
130}
131
132sub reinitialize {
133 my $self = shift;
134 my $pkg = shift;
135
136 my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg);
137
138 my $cache_key;
139
140 my %existing_classes;
141 if ($meta) {
142 %existing_classes = map { $_ => $meta->$_() } qw(
143 attribute_metaclass
144 method_metaclass
145 wrapped_method_metaclass
146 instance_metaclass
147 constructor_class
148 destructor_class
149 error_class
150 );
151
152 $cache_key = _anon_cache_key(
153 [ $meta->superclasses ],
154 [ map { $_->name } @{ $meta->roles } ],
155 ) if $meta->is_anon_class;
156 }
157
158 my $new_meta = $self->SUPER::reinitialize(
159 $pkg,
160 %existing_classes,
161 @_,
162 );
163
164 return $new_meta unless defined $cache_key;
165
166 my $new_cache_key = _anon_cache_key(
167 [ $meta->superclasses ],
168 [ map { $_->name } @{ $meta->roles } ],
169 );
170
171 delete $ANON_CLASSES{$cache_key};
172 $ANON_CLASSES{$new_cache_key} = $new_meta;
173
174 return $new_meta;
175}
176
ef333f17 177sub add_role {
178 my ($self, $role) = @_;
179 (blessed($role) && $role->isa('Moose::Meta::Role'))
11c86f15 180 || $self->throw_error("Roles must be instances of Moose::Meta::Role", data => $role);
ef333f17 181 push @{$self->roles} => $role;
182}
183
639f9a1a 184sub role_applications {
185 my ($self) = @_;
186
187 return @{$self->_get_role_applications};
188}
189
a9b63d79 190sub add_role_application {
191 my ($self, $application) = @_;
192 (blessed($application) && $application->isa('Moose::Meta::Role::Application::ToClass'))
193 || $self->throw_error("Role applications must be instances of Moose::Meta::Role::Application::ToClass", data => $application);
639f9a1a 194 push @{$self->_get_role_applications} => $application;
a9b63d79 195}
196
b8aeb4dc 197sub calculate_all_roles {
198 my $self = shift;
199 my %seen;
200 grep { !$seen{$_->name}++ } map { $_->calculate_all_roles } @{ $self->roles };
201}
202
ef333f17 203sub does_role {
204 my ($self, $role_name) = @_;
322abb07 205
ef333f17 206 (defined $role_name)
11c86f15 207 || $self->throw_error("You must supply a role name to look for");
322abb07 208
9c429218 209 foreach my $class ($self->class_precedence_list) {
322abb07 210 my $meta = Class::MOP::class_of($class);
3d0f5a27 211 # when a Moose metaclass is itself extended with a role,
212 # this check needs to be done since some items in the
213 # class_precedence_list might in fact be Class::MOP
214 # based still.
322abb07 215 next unless $meta && $meta->can('roles');
216 foreach my $role (@{$meta->roles}) {
9c429218 217 return 1 if $role->does_role($role_name);
218 }
ef333f17 219 }
220 return 0;
221}
222
d79e62fd 223sub excludes_role {
224 my ($self, $role_name) = @_;
ebfc4d0f 225
d79e62fd 226 (defined $role_name)
11c86f15 227 || $self->throw_error("You must supply a role name to look for");
ebfc4d0f 228
ac2dc464 229 foreach my $class ($self->class_precedence_list) {
ebfc4d0f 230 my $meta = Class::MOP::class_of($class);
231 # when a Moose metaclass is itself extended with a role,
232 # this check needs to be done since some items in the
233 # class_precedence_list might in fact be Class::MOP
234 # based still.
235 next unless $meta && $meta->can('roles');
236 foreach my $role (@{$meta->roles}) {
9c429218 237 return 1 if $role->excludes_role($role_name);
238 }
d79e62fd 239 }
240 return 0;
241}
242
8c9d74e7 243sub new_object {
7d4035ae 244 my $self = shift;
e606ae5f 245 my $params = @_ == 1 ? $_[0] : {@_};
7d4035ae 246 my $object = $self->SUPER::new_object($params);
1308deb4 247
7d4035ae 248 foreach my $attr ( $self->get_all_attributes() ) {
1308deb4 249
250 next unless $attr->can('has_trigger') && $attr->has_trigger;
251
252 my $init_arg = $attr->init_arg;
253
254 next unless defined $init_arg;
255
256 next unless exists $params->{$init_arg};
257
258 $attr->trigger->(
7d4035ae 259 $object,
1308deb4 260 (
261 $attr->should_coerce
7d4035ae 262 ? $attr->get_read_method_ref->($object)
1308deb4 263 : $params->{$init_arg}
264 ),
1308deb4 265 );
8c9d74e7 266 }
1308deb4 267
7d4035ae 268 $object->BUILDALL($params) if $object->can('BUILDALL');
a19ae3d7 269
7d4035ae 270 return $object;
8c9d74e7 271}
272
e2eef3a5 273sub superclasses {
274 my $self = shift;
2e7f6cf4 275 my $supers = Data::OptList::mkopt(\@_);
276 foreach my $super (@{ $supers }) {
277 my ($name, $opts) = @{ $super };
278 Class::MOP::load_class($name, $opts);
279 my $meta = Class::MOP::class_of($name);
280 $self->throw_error("You cannot inherit from a Moose Role ($name)")
e2eef3a5 281 if $meta && $meta->isa('Moose::Meta::Role')
282 }
2e7f6cf4 283 return $self->SUPER::superclasses(map { $_->[0] } @{ $supers });
e2eef3a5 284}
285
093b12c2 286### ---------------------------------------------
287
a2eec5e7 288sub add_attribute {
289 my $self = shift;
28af3424 290 my $attr =
e472c9a5 291 (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
d03bd989 292 ? $_[0]
28af3424 293 : $self->_process_attribute(@_));
294 $self->SUPER::add_attribute($attr);
295 # it may be a Class::MOP::Attribute, theoretically, which doesn't have
296 # 'bare' and doesn't implement this method
9340e346 297 if ($attr->can('_check_associated_methods')) {
298 $attr->_check_associated_methods;
28af3424 299 }
300 return $attr;
a2eec5e7 301}
302
78cd1d3b 303sub add_override_method_modifier {
304 my ($self, $name, $method, $_super_package) = @_;
18c2ec0e 305
d05cd563 306 (!$self->has_method($name))
11c86f15 307 || $self->throw_error("Cannot add an override method if a local method is already present");
18c2ec0e 308
74862722 309 $self->add_method($name => Moose::Meta::Method::Overridden->new(
3f9e4b0a 310 method => $method,
311 class => $self,
312 package => $_super_package, # need this for roles
313 name => $name,
18c2ec0e 314 ));
78cd1d3b 315}
316
317sub add_augment_method_modifier {
ac2dc464 318 my ($self, $name, $method) = @_;
d05cd563 319 (!$self->has_method($name))
11c86f15 320 || $self->throw_error("Cannot add an augment method if a local method is already present");
3f9e4b0a 321
322 $self->add_method($name => Moose::Meta::Method::Augmented->new(
323 method => $method,
324 class => $self,
325 name => $name,
326 ));
78cd1d3b 327}
328
1341f10c 329## Private Utility methods ...
330
05d9eaf6 331sub _find_next_method_by_name_which_is_not_overridden {
332 my ($self, $name) = @_;
68efb014 333 foreach my $method ($self->find_all_methods_by_name($name)) {
ac2dc464 334 return $method->{code}
74862722 335 if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
05d9eaf6 336 }
337 return undef;
338}
339
f6df97ae 340## Metaclass compatibility
f8b6827f 341
f6df97ae 342sub _base_metaclasses {
343 my $self = shift;
344 my %metaclasses = $self->SUPER::_base_metaclasses;
345 for my $class (keys %metaclasses) {
346 $metaclasses{$class} =~ s/^Class::MOP/Moose::Meta/;
1341f10c 347 }
f6df97ae 348 return (
349 %metaclasses,
350 error_class => 'Moose::Error::Default',
f8b6827f 351 );
f8b6827f 352}
353
f6df97ae 354sub _find_common_base {
355 my $self = shift;
356 my ($meta1, $meta2) = map { Class::MOP::class_of($_) } @_;
357 return unless defined($meta1) && defined($meta2);
f8b6827f 358
359 # FIXME? This doesn't account for multiple inheritance (not sure
360 # if it needs to though). For example, is somewhere in $meta1's
db9fda52 361 # history it inherits from both ClassA and ClassB, and $meta2
f8b6827f 362 # inherits from ClassB & ClassA, does it matter? And what crazy
363 # fool would do that anyway?
364
365 my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
366
367 return first { $meta1_parents{$_} } $meta2->linearized_isa;
368}
369
f6df97ae 370sub _get_ancestors_until {
371 my $self = shift;
dd3ac8f9 372 my ($start_name, $until_name) = @_;
f8b6827f 373
dd3ac8f9 374 my @ancestor_names;
375 for my $ancestor_name (Class::MOP::class_of($start_name)->linearized_isa) {
376 last if $ancestor_name eq $until_name;
377 push @ancestor_names, $ancestor_name;
f6df97ae 378 }
dd3ac8f9 379 return @ancestor_names;
f6df97ae 380}
f8b6827f 381
f6df97ae 382sub _is_role_only_subclass {
383 my $self = shift;
dd3ac8f9 384 my ($meta_name) = @_;
385 my $meta = Class::MOP::Class->initialize($meta_name);
386 my @parent_names = $meta->superclasses;
f6df97ae 387
388 # XXX: don't feel like messing with multiple inheritance here... what would
389 # that even do?
dd3ac8f9 390 return unless @parent_names == 1;
391 my ($parent_name) = @parent_names;
392 my $parent_meta = Class::MOP::Class->initialize($parent_name);
f6df97ae 393
394 # loop over all methods that are a part of the current class
395 # (not inherited)
dd3ac8f9 396 for my $method (map { $meta->get_method($_) } $meta->get_method_list) {
f6df97ae 397 # always ignore meta
f8b6827f 398 next if $method->name eq 'meta';
f6df97ae 399 # we'll deal with attributes below
400 next if $method->isa('Class::MOP::Method::Accessor');
401 # if the method comes from a role we consumed, ignore it
dd3ac8f9 402 next if $meta->can('does_role')
403 && $meta->does_role($method->original_package_name);
f8b6827f 404
405 return 0;
406 }
407
f6df97ae 408 # loop over all attributes that are a part of the current class
409 # (not inherited)
f8b6827f 410 # FIXME - this really isn't right. Just because an attribute is
411 # defined in a role doesn't mean it isn't _also_ defined in the
412 # subclass.
dd3ac8f9 413 for my $attr (map { $meta->get_attribute($_) } $meta->get_attribute_list) {
f6df97ae 414 next if any { $_->has_attribute($attr->name) }
415 map { $_->meta->can('calculate_all_roles')
416 ? $_->meta->calculate_all_roles
417 : () }
418 $meta->linearized_isa;
f8b6827f 419
420 return 0;
421 }
422
423 return 1;
424}
425
f6df97ae 426sub _can_fix_class_metaclass_incompatibility_by_role_reconciliation {
427 my $self = shift;
428 my ($super_meta) = @_;
429
dd3ac8f9 430 my $common_base_name = $self->_find_common_base(blessed($self), blessed($super_meta));
f6df97ae 431 # if they're not both moose metaclasses, and the cmop fixing couldn't
432 # do anything, there's nothing more we can do
dd3ac8f9 433 return unless defined($common_base_name);
434 return unless $common_base_name->isa('Moose::Meta::Class');
f8b6827f 435
dd3ac8f9 436 my @super_meta_name_ancestor_names = $self->_get_ancestors_until(blessed($super_meta), $common_base_name);
437 my @class_meta_name_ancestor_names = $self->_get_ancestors_until(blessed($self), $common_base_name);
f6df97ae 438 # we're only dealing with roles here
439 return unless all { $self->_is_role_only_subclass($_) }
dd3ac8f9 440 (@super_meta_name_ancestor_names,
441 @class_meta_name_ancestor_names);
f6df97ae 442
443 return 1;
f8b6827f 444}
445
f6df97ae 446sub _can_fix_single_metaclass_incompatibility_by_role_reconciliation {
447 my $self = shift;
dd3ac8f9 448 my ($metaclass_type, $super_meta) = @_;
f8b6827f 449
dd3ac8f9 450 my $class_specific_meta_name = $self->$metaclass_type;
451 return unless $super_meta->can($metaclass_type);
452 my $super_specific_meta_name = $super_meta->$metaclass_type;
f6df97ae 453 my %metaclasses = $self->_base_metaclasses;
f8b6827f 454
dd3ac8f9 455 my $common_base_name = $self->_find_common_base($class_specific_meta_name, $super_specific_meta_name);
f6df97ae 456 # if they're not both moose metaclasses, and the cmop fixing couldn't
457 # do anything, there's nothing more we can do
dd3ac8f9 458 return unless defined($common_base_name);
459 return unless $common_base_name->isa($metaclasses{$metaclass_type});
f8b6827f 460
dd3ac8f9 461 my @super_specific_meta_name_ancestor_names = $self->_get_ancestors_until($super_specific_meta_name, $common_base_name);
462 my @class_specific_meta_name_ancestor_names = $self->_get_ancestors_until($class_specific_meta_name, $common_base_name);
f6df97ae 463 # we're only dealing with roles here
464 return unless all { $self->_is_role_only_subclass($_) }
dd3ac8f9 465 (@super_specific_meta_name_ancestor_names,
466 @class_specific_meta_name_ancestor_names);
f8b6827f 467
f6df97ae 468 return 1;
469}
f8b6827f 470
f6df97ae 471sub _role_differences {
472 my $self = shift;
dd3ac8f9 473 my ($class_meta_name, $super_meta_name) = @_;
474 my @super_role_metas = $super_meta_name->meta->can('calculate_all_roles')
475 ? $super_meta_name->meta->calculate_all_roles
476 : ();
477 my @role_metas = $class_meta_name->meta->can('calculate_all_roles')
478 ? $class_meta_name->meta->calculate_all_roles
479 : ();
f6df97ae 480 my @differences;
dd3ac8f9 481 for my $role_meta (@role_metas) {
482 push @differences, $role_meta
483 unless any { $_->name eq $role_meta->name } @super_role_metas;
f8b6827f 484 }
f6df97ae 485 return @differences;
f8b6827f 486}
487
f6df97ae 488sub _reconcile_roles_for_metaclass {
489 my $self = shift;
dd3ac8f9 490 my ($class_meta_name, $super_meta_name) = @_;
f8b6827f 491
dd3ac8f9 492 my @role_differences = $self->_role_differences(
493 $class_meta_name, $super_meta_name,
494 );
495 return $self->create_anon_class(
496 superclasses => [$super_meta_name],
f6df97ae 497 roles => \@role_differences,
498 cache => 1,
499 );
500}
501
502sub _can_fix_metaclass_incompatibility_by_role_reconciliation {
503 my $self = shift;
504 my ($super_meta) = @_;
f8b6827f 505
f6df97ae 506 return 1 if $self->_can_fix_class_metaclass_incompatibility_by_role_reconciliation($super_meta);
f8b6827f 507
f6df97ae 508 my %base_metaclass = $self->_base_metaclasses;
509 for my $metaclass_type (keys %base_metaclass) {
510 next unless defined $self->$metaclass_type;
511 return 1 if $self->_can_fix_single_metaclass_incompatibility_by_role_reconciliation($metaclass_type, $super_meta);
f8b6827f 512 }
513
f6df97ae 514 return;
515}
f8b6827f 516
f6df97ae 517sub _can_fix_metaclass_incompatibility {
518 my $self = shift;
519 return 1 if $self->_can_fix_metaclass_incompatibility_by_role_reconciliation(@_);
520 return $self->SUPER::_can_fix_metaclass_incompatibility(@_);
521}
522
523sub _fix_class_metaclass_incompatibility {
524 my $self = shift;
525 my ($super_meta) = @_;
f8b6827f 526
f6df97ae 527 $self->SUPER::_fix_class_metaclass_incompatibility(@_);
f8b6827f 528
f6df97ae 529 if ($self->_can_fix_class_metaclass_incompatibility_by_role_reconciliation($super_meta)) {
dd3ac8f9 530 my $class_meta_subclass_meta = $self->_reconcile_roles_for_metaclass(blessed($self), blessed($super_meta));
531 # XXX: this doesn't work! we're reblessing $self into a subclass of
532 # $super_meta, not of itself... probably do need to just go ahead and
533 # reinitialize things here
534 $class_meta_subclass_meta->rebless_instance($self);
f8b6827f 535 }
f6df97ae 536}
f8b6827f 537
f6df97ae 538sub _fix_single_metaclass_incompatibility {
539 my $self = shift;
540 my ($metaclass_type, $super_meta) = @_;
f8b6827f 541
f6df97ae 542 $self->SUPER::_fix_single_metaclass_incompatibility(@_);
f8b6827f 543
f6df97ae 544 if ($self->_can_fix_single_metaclass_incompatibility_by_role_reconciliation($metaclass_type, $super_meta)) {
545 my %metaclasses = $self->_base_metaclasses;
dd3ac8f9 546 my $class_specific_meta_subclass_meta = $self->_reconcile_roles_for_metaclass($self->$metaclass_type, $super_meta->$metaclass_type);
547 $self->$metaclass_type($class_specific_meta_subclass_meta->name);
f6df97ae 548 }
f8b6827f 549}
550
1341f10c 551sub _process_attribute {
a3738e5b 552 my ( $self, $name, @args ) = @_;
7e59b803 553
554 @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
d9bb6c63 555
f9b5f5f8 556 if (($name || '') =~ /^\+(.*)/) {
7e59b803 557 return $self->_process_inherited_attribute($1, @args);
1341f10c 558 }
559 else {
7e59b803 560 return $self->_process_new_attribute($name, @args);
561 }
562}
563
564sub _process_new_attribute {
565 my ( $self, $name, @args ) = @_;
7e59b803 566
d5c30e52 567 $self->attribute_metaclass->interpolate_class_and_new($name, @args);
1341f10c 568}
569
570sub _process_inherited_attribute {
571 my ($self, $attr_name, %options) = @_;
572 my $inherited_attr = $self->find_attribute_by_name($attr_name);
573 (defined $inherited_attr)
329c5dd4 574 || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
1341f10c 575 if ($inherited_attr->isa('Moose::Meta::Attribute')) {
d7d8a8c7 576 return $inherited_attr->clone_and_inherit_options(%options);
1341f10c 577 }
578 else {
579 # NOTE:
580 # kind of a kludge to handle Class::MOP::Attributes
d7d8a8c7 581 return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
ac2dc464 582 }
1341f10c 583}
584
5cf3dbcf 585## -------------------------------------------------
586
bf6fa6b3 587our $error_level;
11c86f15 588
589sub throw_error {
590 my ( $self, @args ) = @_;
bf6fa6b3 591 local $error_level = ($error_level || 0) + 1;
11c86f15 592 $self->raise_error($self->create_error(@args));
593}
594
595sub raise_error {
596 my ( $self, @args ) = @_;
597 die @args;
598}
599
600sub create_error {
601 my ( $self, @args ) = @_;
602
18748ad6 603 require Carp::Heavy;
604
bf6fa6b3 605 local $error_level = ($error_level || 0 ) + 1;
18748ad6 606
11c86f15 607 if ( @args % 2 == 1 ) {
608 unshift @args, "message";
609 }
610
fcab1742 611 my %args = ( metaclass => $self, last_error => $@, @args );
11c86f15 612
bf6fa6b3 613 $args{depth} += $error_level;
11c86f15 614
bf6fa6b3 615 my $class = ref $self ? $self->error_class : "Moose::Error::Default";
11c86f15 616
a810a01f 617 Class::MOP::load_class($class);
618
11c86f15 619 $class->new(
bf6fa6b3 620 Carp::caller_info($args{depth}),
621 %args
11c86f15 622 );
623}
624
c0e30cf5 6251;
626
627__END__
628
629=pod
630
631=head1 NAME
632
e522431d 633Moose::Meta::Class - The Moose metaclass
c0e30cf5 634
c0e30cf5 635=head1 DESCRIPTION
636
70bb0f97 637This class is a subclass of L<Class::MOP::Class> that provides
638additional Moose-specific functionality.
e522431d 639
7854b409 640To really understand this class, you will need to start with the
641L<Class::MOP::Class> documentation. This class can be understood as a
642set of additional features on top of the basic feature provided by
643that parent class.
6ba6d68c 644
d4b1449e 645=head1 INHERITANCE
646
647C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
648
c0e30cf5 649=head1 METHODS
650
651=over 4
652
70bb0f97 653=item B<< Moose::Meta::Class->initialize($package_name, %options) >>
590868a3 654
70bb0f97 655This overrides the parent's method in order to provide its own
656defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
657C<method_metaclass> options.
61bdd94f 658
70bb0f97 659These all default to the appropriate Moose class.
61bdd94f 660
70bb0f97 661=item B<< Moose::Meta::Class->create($package_name, %options) >>
17594769 662
70bb0f97 663This overrides the parent's method in order to accept a C<roles>
9e25a72a 664option. This should be an array reference containing roles
665that the class does, each optionally followed by a hashref of options
666(C<-excludes> and C<-alias>).
17594769 667
70bb0f97 668 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
17594769 669
70bb0f97 670=item B<< Moose::Meta::Class->create_anon_class >>
17594769 671
70bb0f97 672This overrides the parent's method to accept a C<roles> option, just
673as C<create> does.
5cf3dbcf 674
70bb0f97 675It also accepts a C<cache> option. If this is true, then the anonymous
676class will be cached based on its superclasses and roles. If an
677existing anonymous class in the cache has the same superclasses and
678roles, it will be reused.
ac2dc464 679
70bb0f97 680 my $metaclass = Moose::Meta::Class->create_anon_class(
681 superclasses => ['Foo'],
682 roles => [qw/Some Roles Go Here/],
683 cache => 1,
684 );
ac2dc464 685
2e7f6cf4 686Each entry in both the C<superclasses> and the C<roles> option can be
b2d54db8 687followed by a hash reference with arguments. The C<superclasses>
2e7f6cf4 688option can be supplied with a L<-version|Class::MOP/Class Loading
689Options> option that ensures the loaded superclass satisfies the
690required version. The C<role> option also takes the C<-version> as an
691argument, but the option hash reference can also contain any other
692role relevant values like exclusions or parameterized role arguments.
693
70bb0f97 694=item B<< $metaclass->make_immutable(%options) >>
ac2dc464 695
70bb0f97 696This overrides the parent's method to add a few options. Specifically,
697it uses the Moose-specific constructor and destructor classes, and
698enables inlining the destructor.
8c9d74e7 699
70bb0f97 700Also, since Moose always inlines attributes, it sets the
701C<inline_accessors> option to false.
02a0fb52 702
70bb0f97 703=item B<< $metaclass->new_object(%params) >>
a15dff8d 704
70bb0f97 705This overrides the parent's method in order to add support for
706attribute triggers.
6ba6d68c 707
2e7f6cf4 708=item B<< $metaclass->superclasses(@superclasses) >>
709
6b958a3e 710This is the accessor allowing you to read or change the parents of
2e7f6cf4 711the class.
712
713Each superclass can be followed by a hash reference containing a
714L<-version|Class::MOP/Class Loading Options> value. If the version
715requirement is not satisfied an error will be thrown.
716
70bb0f97 717=item B<< $metaclass->add_override_method_modifier($name, $sub) >>
ef1d5f4b 718
70bb0f97 719This adds an C<override> method modifier to the package.
e9ec68d6 720
70bb0f97 721=item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
e9ec68d6 722
70bb0f97 723This adds an C<augment> method modifier to the package.
78cd1d3b 724
70bb0f97 725=item B<< $metaclass->calculate_all_roles >>
02a0fb52 726
70bb0f97 727This will return a unique array of C<Moose::Meta::Role> instances
728which are attached to this class.
78cd1d3b 729
70bb0f97 730=item B<< $metaclass->add_role($role) >>
02a0fb52 731
70bb0f97 732This takes a L<Moose::Meta::Role> object, and adds it to the class's
733list of roles. This I<does not> actually apply the role to the class.
2b14ac61 734
b90dd4ef 735=item B<< $metaclass->role_applications >>
736
639f9a1a 737Returns a list of L<Moose::Meta::Role::Application::ToClass>
b90dd4ef 738objects, which contain the arguments to role application.
739
740=item B<< $metaclass->add_role_application($application) >>
741
742This takes a L<Moose::Meta::Role::Application::ToClass> object, and
743adds it to the class's list of role applications. This I<does not>
744actually apply any role to the class; it is only for tracking role
745applications.
746
560c498d 747=item B<< $metaclass->does_role($role) >>
ef333f17 748
560c498d 749This returns a boolean indicating whether or not the class does the specified
750role. The role provided can be either a role name or a L<Moose::Meta::Role>
751object. This tests both the class and its parents.
02a0fb52 752
70bb0f97 753=item B<< $metaclass->excludes_role($role_name) >>
ef333f17 754
70bb0f97 755A class excludes a role if it has already composed a role which
756excludes the named role. This tests both the class and its parents.
02a0fb52 757
70bb0f97 758=item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
ef333f17 759
70bb0f97 760This overrides the parent's method in order to allow the parameters to
761be provided as a hash reference.
02a0fb52 762
9f9fdd08 763=item B<< $metaclass->constructor_class($class_name) >>
d79e62fd 764
9f9fdd08 765=item B<< $metaclass->destructor_class($class_name) >>
e606ae5f 766
767These are the names of classes used when making a class
768immutable. These default to L<Moose::Meta::Method::Constructor> and
769L<Moose::Meta::Method::Destructor> respectively. These accessors are
770read-write, so you can use them to change the class name.
771
70bb0f97 772=item B<< $metaclass->error_class($class_name) >>
8b1d510f 773
70bb0f97 774The name of the class used to throw errors. This defaults to
8b1d510f 775L<Moose::Error::Default>, which generates an error with a stacktrace
776just like C<Carp::confess>.
777
70bb0f97 778=item B<< $metaclass->throw_error($message, %extra) >>
11c86f15 779
780Throws the error created by C<create_error> using C<raise_error>
781
c0e30cf5 782=back
783
784=head1 BUGS
785
d4048ef3 786See L<Moose/BUGS> for details on reporting bugs.
c0e30cf5 787
c0e30cf5 788=head1 AUTHOR
789
790Stevan Little E<lt>stevan@iinteractive.comE<gt>
791
792=head1 COPYRIGHT AND LICENSE
793
7e0492d3 794Copyright 2006-2010 by Infinity Interactive, Inc.
c0e30cf5 795
796L<http://www.iinteractive.com>
797
798This library is free software; you can redistribute it and/or modify
ac2dc464 799it under the same terms as Perl itself.
c0e30cf5 800
8a7a9c53 801=cut
1a563243 802