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