Use dzil Authority plugin - remove $AUTHORITY from code
[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
590e8894 9use Carp qw( confess );
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
74862722 15use Moose::Meta::Method::Overridden;
3f9e4b0a 16use Moose::Meta::Method::Augmented;
77f14411 17use Moose::Error::Default;
0fa70d03 18use Moose::Meta::Class::Immutable::Trait;
19use Moose::Meta::Method::Constructor;
20use Moose::Meta::Method::Destructor;
699a2e32 21use Moose::Meta::Method::Meta;
61907a02 22use Moose::Util;
d2782813 23use Class::MOP::MiniTrait;
8ee73eeb 24
c0e30cf5 25use base 'Class::MOP::Class';
26
d2782813 27Class::MOP::MiniTrait::apply(__PACKAGE__, 'Moose::Meta::Object::Trait');
28
598340d5 29__PACKAGE__->meta->add_attribute('roles' => (
ef333f17 30 reader => 'roles',
31 default => sub { [] }
32));
33
a9b63d79 34__PACKAGE__->meta->add_attribute('role_applications' => (
639f9a1a 35 reader => '_get_role_applications',
a9b63d79 36 default => sub { [] }
37));
38
0fa70d03 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
e606ae5f 46__PACKAGE__->meta->add_attribute('constructor_class' => (
47 accessor => 'constructor_class',
e0001338 48 default => 'Moose::Meta::Method::Constructor',
e606ae5f 49));
50
51__PACKAGE__->meta->add_attribute('destructor_class' => (
52 accessor => 'destructor_class',
e0001338 53 default => 'Moose::Meta::Method::Destructor',
e606ae5f 54));
55
11c86f15 56__PACKAGE__->meta->add_attribute('error_class' => (
bf6fa6b3 57 accessor => 'error_class',
58 default => 'Moose::Error::Default',
11c86f15 59));
60
590868a3 61sub initialize {
62 my $class = shift;
63 my $pkg = shift;
d03bd989 64 return Class::MOP::get_metaclass_by_name($pkg)
685f7e44 65 || $class->SUPER::initialize($pkg,
66 'attribute_metaclass' => 'Moose::Meta::Attribute',
67 'method_metaclass' => 'Moose::Meta::Method',
68 'instance_metaclass' => 'Moose::Meta::Instance',
69 @_
d03bd989 70 );
ac2dc464 71}
590868a3 72
61bdd94f 73sub create {
7d4035ae 74 my ($class, $package_name, %options) = @_;
d03bd989 75
61bdd94f 76 (ref $options{roles} eq 'ARRAY')
7d4035ae 77 || $class->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
61bdd94f 78 if exists $options{roles};
310ba883 79 my $roles = delete $options{roles};
dd37a5be 80
7d4035ae 81 my $new_meta = $class->SUPER::create($package_name, %options);
dd37a5be 82
310ba883 83 if ($roles) {
7d4035ae 84 Moose::Util::apply_all_roles( $new_meta, @$roles );
61bdd94f 85 }
d03bd989 86
7d4035ae 87 return $new_meta;
61bdd94f 88}
89
17594769 90my %ANON_CLASSES;
91
92sub create_anon_class {
93 my ($self, %options) = @_;
94
95 my $cache_ok = delete $options{cache};
d03bd989 96
cf600c83 97 my $cache_key
98 = _anon_cache_key( $options{superclasses}, $options{roles} );
d03bd989 99
6d5cbd2b 100 if ($cache_ok && defined $ANON_CLASSES{$cache_key}) {
17594769 101 return $ANON_CLASSES{$cache_key};
102 }
d03bd989 103
dcc8dc06 104 $options{weaken} = !$cache_ok
105 unless exists $options{weaken};
106
17594769 107 my $new_class = $self->SUPER::create_anon_class(%options);
108
dcc8dc06 109 if ($cache_ok) {
110 $ANON_CLASSES{$cache_key} = $new_class;
111 weaken($ANON_CLASSES{$cache_key});
112 }
17594769 113
114 return $new_class;
115}
116
699a2e32 117sub _meta_method_class { 'Moose::Meta::Method::Meta' }
118
cf600c83 119sub _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
127sub 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;
dcc8dc06 168 weaken($ANON_CLASSES{$new_cache_key});
cf600c83 169
170 return $new_meta;
171}
172
ef333f17 173sub add_role {
174 my ($self, $role) = @_;
175 (blessed($role) && $role->isa('Moose::Meta::Role'))
11c86f15 176 || $self->throw_error("Roles must be instances of Moose::Meta::Role", data => $role);
ef333f17 177 push @{$self->roles} => $role;
178}
179
639f9a1a 180sub role_applications {
181 my ($self) = @_;
182
183 return @{$self->_get_role_applications};
184}
185
a9b63d79 186sub 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);
639f9a1a 190 push @{$self->_get_role_applications} => $application;
a9b63d79 191}
192
b8aeb4dc 193sub calculate_all_roles {
194 my $self = shift;
195 my %seen;
196 grep { !$seen{$_->name}++ } map { $_->calculate_all_roles } @{ $self->roles };
197}
198
9f83eb5d 199sub 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
ef333f17 209sub does_role {
210 my ($self, $role_name) = @_;
322abb07 211
ef333f17 212 (defined $role_name)
11c86f15 213 || $self->throw_error("You must supply a role name to look for");
322abb07 214
9c429218 215 foreach my $class ($self->class_precedence_list) {
322abb07 216 my $meta = Class::MOP::class_of($class);
3d0f5a27 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.
322abb07 221 next unless $meta && $meta->can('roles');
222 foreach my $role (@{$meta->roles}) {
9c429218 223 return 1 if $role->does_role($role_name);
224 }
ef333f17 225 }
226 return 0;
227}
228
d79e62fd 229sub excludes_role {
230 my ($self, $role_name) = @_;
ebfc4d0f 231
d79e62fd 232 (defined $role_name)
11c86f15 233 || $self->throw_error("You must supply a role name to look for");
ebfc4d0f 234
ac2dc464 235 foreach my $class ($self->class_precedence_list) {
ebfc4d0f 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}) {
9c429218 243 return 1 if $role->excludes_role($role_name);
244 }
d79e62fd 245 }
246 return 0;
247}
248
8c9d74e7 249sub new_object {
7d4035ae 250 my $self = shift;
e606ae5f 251 my $params = @_ == 1 ? $_[0] : {@_};
7d4035ae 252 my $object = $self->SUPER::new_object($params);
1308deb4 253
7d4035ae 254 foreach my $attr ( $self->get_all_attributes() ) {
1308deb4 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->(
7d4035ae 265 $object,
1308deb4 266 (
267 $attr->should_coerce
7d4035ae 268 ? $attr->get_read_method_ref->($object)
1308deb4 269 : $params->{$init_arg}
270 ),
1308deb4 271 );
8c9d74e7 272 }
1308deb4 273
7d4035ae 274 $object->BUILDALL($params) if $object->can('BUILDALL');
a19ae3d7 275
7d4035ae 276 return $object;
8c9d74e7 277}
278
e3225a0f 279sub _generate_fallback_constructor {
280 my $self = shift;
281 my ($class) = @_;
282 return $class . '->Moose::Object::new(@_)'
283}
284
285sub _inline_params {
286 my $self = shift;
287 my ($params, $class) = @_;
288 return (
289 'my ' . $params . ' = ',
290 $self->_inline_BUILDARGS($class, '@_'),
291 ';',
292 );
293}
294
295sub _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
335sub _inline_slot_initializer {
336 my $self = shift;
ec86bdff 337 my ($attr, $idx) = @_;
e3225a0f 338
ec86bdff 339 return (
340 '## ' . $attr->name,
341 $self->_inline_check_required_attr($attr),
342 $self->SUPER::_inline_slot_initializer(@_),
343 );
e3225a0f 344}
345
346sub _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
7106ce79 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
e3225a0f 366sub _inline_init_attr_from_constructor {
367 my $self = shift;
ec86bdff 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',
e3225a0f 376 );
377
ec86bdff 378 push @initial_value, (
379 '$attrs->[' . $idx . ']->set_initial_value(',
380 '$instance,',
381 $attr->_inline_instance_get('$instance'),
382 ');',
383 ) if $attr->has_initializer;
e3225a0f 384
ec86bdff 385 return @initial_value;
e3225a0f 386}
387
ec86bdff 388sub _inline_init_attr_from_default {
e3225a0f 389 my $self = shift;
ec86bdff 390 my ($attr, $idx) = @_;
e3225a0f 391
ec86bdff 392 my $default = $self->_inline_default_value($attr, $idx);
393 return unless $default;
e3225a0f 394
ec86bdff 395 my @initial_value = (
396 'my $default = ' . $default . ';',
397 $attr->_inline_set_value(
398 '$instance',
399 '$default',
400 '$type_constraint_bodies[' . $idx . ']',
401 '$type_constraints[' . $idx . ']',
402 'for constructor',
403 ),
e3225a0f 404 );
405
ec86bdff 406 push @initial_value, (
407 '$attrs->[' . $idx . ']->set_initial_value(',
408 '$instance,',
409 $attr->_inline_instance_get('$instance'),
410 ');',
411 ) if $attr->has_initializer;
e3225a0f 412
ec86bdff 413 return @initial_value;
e3225a0f 414}
415
416sub _inline_extra_init {
417 my $self = shift;
418 return (
419 $self->_inline_triggers,
420 $self->_inline_BUILDALL,
421 );
422}
423
424sub _inline_triggers {
425 my $self = shift;
426 my @trigger_calls;
427
ec86bdff 428 my @attrs = sort { $a->name cmp $b->name } $self->get_all_attributes;
e3225a0f 429 for my $i (0 .. $#attrs) {
430 my $attr = $attrs[$i];
431
432 next unless $attr->can('has_trigger') && $attr->has_trigger;
433
434 my $init_arg = $attr->init_arg;
435 next unless defined $init_arg;
436
437 push @trigger_calls,
438 'if (exists $params->{\'' . $init_arg . '\'}) {',
439 '$attrs->[' . $i . ']->trigger->(',
440 '$instance,',
441 $attr->_inline_instance_get('$instance') . ',',
442 ');',
443 '}';
444 }
445
446 return @trigger_calls;
447}
448
449sub _inline_BUILDALL {
450 my $self = shift;
451
452 my @methods = reverse $self->find_all_methods_by_name('BUILD');
453 my @BUILD_calls;
454
455 foreach my $method (@methods) {
456 push @BUILD_calls,
457 '$instance->' . $method->{class} . '::BUILD($params);';
458 }
459
460 return @BUILD_calls;
461}
462
e2eef3a5 463sub superclasses {
464 my $self = shift;
2e7f6cf4 465 my $supers = Data::OptList::mkopt(\@_);
466 foreach my $super (@{ $supers }) {
467 my ($name, $opts) = @{ $super };
468 Class::MOP::load_class($name, $opts);
469 my $meta = Class::MOP::class_of($name);
470 $self->throw_error("You cannot inherit from a Moose Role ($name)")
e2eef3a5 471 if $meta && $meta->isa('Moose::Meta::Role')
472 }
2e7f6cf4 473 return $self->SUPER::superclasses(map { $_->[0] } @{ $supers });
e2eef3a5 474}
475
093b12c2 476### ---------------------------------------------
477
a2eec5e7 478sub add_attribute {
479 my $self = shift;
28af3424 480 my $attr =
e472c9a5 481 (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
d03bd989 482 ? $_[0]
28af3424 483 : $self->_process_attribute(@_));
484 $self->SUPER::add_attribute($attr);
485 # it may be a Class::MOP::Attribute, theoretically, which doesn't have
486 # 'bare' and doesn't implement this method
9340e346 487 if ($attr->can('_check_associated_methods')) {
488 $attr->_check_associated_methods;
28af3424 489 }
490 return $attr;
a2eec5e7 491}
492
78cd1d3b 493sub add_override_method_modifier {
494 my ($self, $name, $method, $_super_package) = @_;
18c2ec0e 495
d05cd563 496 (!$self->has_method($name))
11c86f15 497 || $self->throw_error("Cannot add an override method if a local method is already present");
18c2ec0e 498
74862722 499 $self->add_method($name => Moose::Meta::Method::Overridden->new(
3f9e4b0a 500 method => $method,
501 class => $self,
502 package => $_super_package, # need this for roles
503 name => $name,
18c2ec0e 504 ));
78cd1d3b 505}
506
507sub add_augment_method_modifier {
ac2dc464 508 my ($self, $name, $method) = @_;
d05cd563 509 (!$self->has_method($name))
11c86f15 510 || $self->throw_error("Cannot add an augment method if a local method is already present");
3f9e4b0a 511
512 $self->add_method($name => Moose::Meta::Method::Augmented->new(
513 method => $method,
514 class => $self,
515 name => $name,
516 ));
78cd1d3b 517}
518
1341f10c 519## Private Utility methods ...
520
05d9eaf6 521sub _find_next_method_by_name_which_is_not_overridden {
522 my ($self, $name) = @_;
68efb014 523 foreach my $method ($self->find_all_methods_by_name($name)) {
ac2dc464 524 return $method->{code}
74862722 525 if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
05d9eaf6 526 }
527 return undef;
528}
529
f6df97ae 530## Metaclass compatibility
f8b6827f 531
f6df97ae 532sub _base_metaclasses {
533 my $self = shift;
534 my %metaclasses = $self->SUPER::_base_metaclasses;
535 for my $class (keys %metaclasses) {
536 $metaclasses{$class} =~ s/^Class::MOP/Moose::Meta/;
1341f10c 537 }
f6df97ae 538 return (
539 %metaclasses,
540 error_class => 'Moose::Error::Default',
f8b6827f 541 );
f8b6827f 542}
543
f6df97ae 544sub _fix_class_metaclass_incompatibility {
545 my $self = shift;
546 my ($super_meta) = @_;
f8b6827f 547
f6df97ae 548 $self->SUPER::_fix_class_metaclass_incompatibility(@_);
f8b6827f 549
88f2e008 550 if ($self->_class_metaclass_can_be_made_compatible($super_meta)) {
590e8894 551 ($self->is_pristine)
552 || confess "Can't fix metaclass incompatibility for "
553 . $self->name
554 . " because it is not pristine.";
a907317a 555 my $super_meta_name = $super_meta->_real_ref_name;
61907a02 556 my $class_meta_subclass_meta_name = Moose::Util::_reconcile_roles_for_metaclass(blessed($self), $super_meta_name);
8450b001 557 my $new_self = $class_meta_subclass_meta_name->reinitialize(
cf7febc7 558 $self->name,
559 );
6a52b083 560
8450b001 561 $self->_replace_self( $new_self, $class_meta_subclass_meta_name );
f8b6827f 562 }
f6df97ae 563}
f8b6827f 564
f6df97ae 565sub _fix_single_metaclass_incompatibility {
566 my $self = shift;
567 my ($metaclass_type, $super_meta) = @_;
f8b6827f 568
f6df97ae 569 $self->SUPER::_fix_single_metaclass_incompatibility(@_);
f8b6827f 570
88f2e008 571 if ($self->_single_metaclass_can_be_made_compatible($super_meta, $metaclass_type)) {
590e8894 572 ($self->is_pristine)
573 || confess "Can't fix metaclass incompatibility for "
574 . $self->name
575 . " because it is not pristine.";
7f6c8567 576 my $super_meta_name = $super_meta->_real_ref_name;
61907a02 577 my $class_specific_meta_subclass_meta_name = Moose::Util::_reconcile_roles_for_metaclass($self->$metaclass_type, $super_meta->$metaclass_type);
cf7febc7 578 my $new_self = $super_meta->reinitialize(
579 $self->name,
8450b001 580 $metaclass_type => $class_specific_meta_subclass_meta_name,
cf7febc7 581 );
6a52b083 582
7f6c8567 583 $self->_replace_self( $new_self, $super_meta_name );
f6df97ae 584 }
f8b6827f 585}
586
6a52b083 587sub _replace_self {
588 my $self = shift;
589 my ( $new_self, $new_class) = @_;
590
591 %$self = %$new_self;
592 bless $self, $new_class;
593
594 # We need to replace the cached metaclass instance or else when it goes
595 # out of scope Class::MOP::Class destroy's the namespace for the
596 # metaclass's class, causing much havoc.
dcc8dc06 597 my $weaken = Class::MOP::metaclass_is_weak( $self->name );
6a52b083 598 Class::MOP::store_metaclass_by_name( $self->name, $self );
dcc8dc06 599 Class::MOP::weaken_metaclass( $self->name ) if $weaken;
6a52b083 600}
601
1341f10c 602sub _process_attribute {
a3738e5b 603 my ( $self, $name, @args ) = @_;
7e59b803 604
605 @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
d9bb6c63 606
f9b5f5f8 607 if (($name || '') =~ /^\+(.*)/) {
7e59b803 608 return $self->_process_inherited_attribute($1, @args);
1341f10c 609 }
610 else {
7e59b803 611 return $self->_process_new_attribute($name, @args);
612 }
613}
614
615sub _process_new_attribute {
616 my ( $self, $name, @args ) = @_;
7e59b803 617
d5c30e52 618 $self->attribute_metaclass->interpolate_class_and_new($name, @args);
1341f10c 619}
620
621sub _process_inherited_attribute {
622 my ($self, $attr_name, %options) = @_;
623 my $inherited_attr = $self->find_attribute_by_name($attr_name);
624 (defined $inherited_attr)
329c5dd4 625 || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
1341f10c 626 if ($inherited_attr->isa('Moose::Meta::Attribute')) {
d7d8a8c7 627 return $inherited_attr->clone_and_inherit_options(%options);
1341f10c 628 }
629 else {
630 # NOTE:
631 # kind of a kludge to handle Class::MOP::Attributes
d7d8a8c7 632 return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
ac2dc464 633 }
1341f10c 634}
635
948cd189 636## Immutability
637
638sub _immutable_options {
639 my ( $self, @args ) = @_;
640
641 $self->SUPER::_immutable_options(
642 inline_destructor => 1,
948cd189 643
644 # Moose always does this when an attribute is created
645 inline_accessors => 0,
646
647 @args,
648 );
649}
650
5cf3dbcf 651## -------------------------------------------------
652
bf6fa6b3 653our $error_level;
11c86f15 654
655sub throw_error {
656 my ( $self, @args ) = @_;
bf6fa6b3 657 local $error_level = ($error_level || 0) + 1;
11c86f15 658 $self->raise_error($self->create_error(@args));
659}
660
e3225a0f 661sub _inline_throw_error {
662 my ( $self, $msg, $args ) = @_;
663 "\$meta->throw_error($msg" . ($args ? ", $args" : "") . ")"; # FIXME makes deparsing *REALLY* hard
664}
665
11c86f15 666sub raise_error {
667 my ( $self, @args ) = @_;
668 die @args;
669}
670
671sub create_error {
672 my ( $self, @args ) = @_;
673
18748ad6 674 require Carp::Heavy;
675
bf6fa6b3 676 local $error_level = ($error_level || 0 ) + 1;
18748ad6 677
11c86f15 678 if ( @args % 2 == 1 ) {
679 unshift @args, "message";
680 }
681
fcab1742 682 my %args = ( metaclass => $self, last_error => $@, @args );
11c86f15 683
bf6fa6b3 684 $args{depth} += $error_level;
11c86f15 685
bf6fa6b3 686 my $class = ref $self ? $self->error_class : "Moose::Error::Default";
11c86f15 687
a810a01f 688 Class::MOP::load_class($class);
689
11c86f15 690 $class->new(
bf6fa6b3 691 Carp::caller_info($args{depth}),
692 %args
11c86f15 693 );
694}
695
c0e30cf5 6961;
697
ad46f524 698# ABSTRACT: The Moose metaclass
699
c0e30cf5 700__END__
701
702=pod
703
c0e30cf5 704=head1 DESCRIPTION
705
70bb0f97 706This class is a subclass of L<Class::MOP::Class> that provides
707additional Moose-specific functionality.
e522431d 708
7854b409 709To really understand this class, you will need to start with the
710L<Class::MOP::Class> documentation. This class can be understood as a
711set of additional features on top of the basic feature provided by
712that parent class.
6ba6d68c 713
d4b1449e 714=head1 INHERITANCE
715
716C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
717
c0e30cf5 718=head1 METHODS
719
720=over 4
721
70bb0f97 722=item B<< Moose::Meta::Class->initialize($package_name, %options) >>
590868a3 723
70bb0f97 724This overrides the parent's method in order to provide its own
725defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
726C<method_metaclass> options.
61bdd94f 727
70bb0f97 728These all default to the appropriate Moose class.
61bdd94f 729
70bb0f97 730=item B<< Moose::Meta::Class->create($package_name, %options) >>
17594769 731
70bb0f97 732This overrides the parent's method in order to accept a C<roles>
9e25a72a 733option. This should be an array reference containing roles
734that the class does, each optionally followed by a hashref of options
735(C<-excludes> and C<-alias>).
17594769 736
70bb0f97 737 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
17594769 738
70bb0f97 739=item B<< Moose::Meta::Class->create_anon_class >>
17594769 740
70bb0f97 741This overrides the parent's method to accept a C<roles> option, just
742as C<create> does.
5cf3dbcf 743
70bb0f97 744It also accepts a C<cache> option. If this is true, then the anonymous
745class will be cached based on its superclasses and roles. If an
746existing anonymous class in the cache has the same superclasses and
747roles, it will be reused.
ac2dc464 748
70bb0f97 749 my $metaclass = Moose::Meta::Class->create_anon_class(
750 superclasses => ['Foo'],
751 roles => [qw/Some Roles Go Here/],
752 cache => 1,
753 );
ac2dc464 754
2e7f6cf4 755Each entry in both the C<superclasses> and the C<roles> option can be
b2d54db8 756followed by a hash reference with arguments. The C<superclasses>
2e7f6cf4 757option can be supplied with a L<-version|Class::MOP/Class Loading
758Options> option that ensures the loaded superclass satisfies the
759required version. The C<role> option also takes the C<-version> as an
760argument, but the option hash reference can also contain any other
761role relevant values like exclusions or parameterized role arguments.
762
70bb0f97 763=item B<< $metaclass->make_immutable(%options) >>
ac2dc464 764
70bb0f97 765This overrides the parent's method to add a few options. Specifically,
766it uses the Moose-specific constructor and destructor classes, and
767enables inlining the destructor.
8c9d74e7 768
dcdceb38 769Since Moose always inlines attributes, it sets the C<inline_accessors> option
770to false.
771
70bb0f97 772=item B<< $metaclass->new_object(%params) >>
a15dff8d 773
70bb0f97 774This overrides the parent's method in order to add support for
775attribute triggers.
6ba6d68c 776
2e7f6cf4 777=item B<< $metaclass->superclasses(@superclasses) >>
778
6b958a3e 779This is the accessor allowing you to read or change the parents of
2e7f6cf4 780the class.
781
782Each superclass can be followed by a hash reference containing a
783L<-version|Class::MOP/Class Loading Options> value. If the version
784requirement is not satisfied an error will be thrown.
785
70bb0f97 786=item B<< $metaclass->add_override_method_modifier($name, $sub) >>
ef1d5f4b 787
70bb0f97 788This adds an C<override> method modifier to the package.
e9ec68d6 789
70bb0f97 790=item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
e9ec68d6 791
70bb0f97 792This adds an C<augment> method modifier to the package.
78cd1d3b 793
70bb0f97 794=item B<< $metaclass->calculate_all_roles >>
02a0fb52 795
70bb0f97 796This will return a unique array of C<Moose::Meta::Role> instances
797which are attached to this class.
78cd1d3b 798
9f83eb5d 799=item B<< $metaclass->calculate_all_roles_with_inheritance >>
800
801This will return a unique array of C<Moose::Meta::Role> instances
802which are attached to this class, and each of this class's ancestors.
803
70bb0f97 804=item B<< $metaclass->add_role($role) >>
02a0fb52 805
70bb0f97 806This takes a L<Moose::Meta::Role> object, and adds it to the class's
807list of roles. This I<does not> actually apply the role to the class.
2b14ac61 808
b90dd4ef 809=item B<< $metaclass->role_applications >>
810
639f9a1a 811Returns a list of L<Moose::Meta::Role::Application::ToClass>
b90dd4ef 812objects, which contain the arguments to role application.
813
814=item B<< $metaclass->add_role_application($application) >>
815
816This takes a L<Moose::Meta::Role::Application::ToClass> object, and
817adds it to the class's list of role applications. This I<does not>
818actually apply any role to the class; it is only for tracking role
819applications.
820
560c498d 821=item B<< $metaclass->does_role($role) >>
ef333f17 822
560c498d 823This returns a boolean indicating whether or not the class does the specified
824role. The role provided can be either a role name or a L<Moose::Meta::Role>
825object. This tests both the class and its parents.
02a0fb52 826
70bb0f97 827=item B<< $metaclass->excludes_role($role_name) >>
ef333f17 828
70bb0f97 829A class excludes a role if it has already composed a role which
830excludes the named role. This tests both the class and its parents.
02a0fb52 831
70bb0f97 832=item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
ef333f17 833
70bb0f97 834This overrides the parent's method in order to allow the parameters to
835be provided as a hash reference.
02a0fb52 836
9f9fdd08 837=item B<< $metaclass->constructor_class($class_name) >>
d79e62fd 838
9f9fdd08 839=item B<< $metaclass->destructor_class($class_name) >>
e606ae5f 840
948cd189 841These are the names of classes used when making a class immutable. These
90a49845 842default to L<Moose::Meta::Method::Constructor> and
843L<Moose::Meta::Method::Destructor> respectively. These accessors are
844read-write, so you can use them to change the class name.
e606ae5f 845
70bb0f97 846=item B<< $metaclass->error_class($class_name) >>
8b1d510f 847
70bb0f97 848The name of the class used to throw errors. This defaults to
8b1d510f 849L<Moose::Error::Default>, which generates an error with a stacktrace
850just like C<Carp::confess>.
851
70bb0f97 852=item B<< $metaclass->throw_error($message, %extra) >>
11c86f15 853
854Throws the error created by C<create_error> using C<raise_error>
855
c0e30cf5 856=back
857
858=head1 BUGS
859
d4048ef3 860See L<Moose/BUGS> for details on reporting bugs.
c0e30cf5 861
8a7a9c53 862=cut
1a563243 863