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