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