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