remove unnecessary(?) 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 );
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 . ']',
384 '$type_constraints[' . $idx . ']',
385 'for constructor',
e3225a0f 386 );
387
ec86bdff 388 push @initial_value, (
389 '$attrs->[' . $idx . ']->set_initial_value(',
390 '$instance,',
391 $attr->_inline_instance_get('$instance'),
392 ');',
393 ) if $attr->has_initializer;
e3225a0f 394
ec86bdff 395 return @initial_value;
e3225a0f 396}
397
ec86bdff 398sub _inline_init_attr_from_default {
e3225a0f 399 my $self = shift;
ec86bdff 400 my ($attr, $idx) = @_;
e3225a0f 401
545c6012 402 return if $attr->can('is_lazy') && $attr->is_lazy;
ec86bdff 403 my $default = $self->_inline_default_value($attr, $idx);
404 return unless $default;
e3225a0f 405
ec86bdff 406 my @initial_value = (
407 'my $default = ' . $default . ';',
408 $attr->_inline_set_value(
409 '$instance',
410 '$default',
411 '$type_constraint_bodies[' . $idx . ']',
412 '$type_constraints[' . $idx . ']',
413 'for constructor',
414 ),
e3225a0f 415 );
416
ec86bdff 417 push @initial_value, (
418 '$attrs->[' . $idx . ']->set_initial_value(',
419 '$instance,',
420 $attr->_inline_instance_get('$instance'),
421 ');',
422 ) if $attr->has_initializer;
e3225a0f 423
ec86bdff 424 return @initial_value;
e3225a0f 425}
426
427sub _inline_extra_init {
428 my $self = shift;
429 return (
430 $self->_inline_triggers,
431 $self->_inline_BUILDALL,
432 );
433}
434
435sub _inline_triggers {
436 my $self = shift;
437 my @trigger_calls;
438
ec86bdff 439 my @attrs = sort { $a->name cmp $b->name } $self->get_all_attributes;
e3225a0f 440 for my $i (0 .. $#attrs) {
441 my $attr = $attrs[$i];
442
443 next unless $attr->can('has_trigger') && $attr->has_trigger;
444
445 my $init_arg = $attr->init_arg;
446 next unless defined $init_arg;
447
448 push @trigger_calls,
449 'if (exists $params->{\'' . $init_arg . '\'}) {',
450 '$attrs->[' . $i . ']->trigger->(',
451 '$instance,',
452 $attr->_inline_instance_get('$instance') . ',',
453 ');',
454 '}';
455 }
456
457 return @trigger_calls;
458}
459
460sub _inline_BUILDALL {
461 my $self = shift;
462
463 my @methods = reverse $self->find_all_methods_by_name('BUILD');
464 my @BUILD_calls;
465
466 foreach my $method (@methods) {
467 push @BUILD_calls,
468 '$instance->' . $method->{class} . '::BUILD($params);';
469 }
470
471 return @BUILD_calls;
472}
473
e2eef3a5 474sub superclasses {
475 my $self = shift;
2e7f6cf4 476 my $supers = Data::OptList::mkopt(\@_);
477 foreach my $super (@{ $supers }) {
478 my ($name, $opts) = @{ $super };
479 Class::MOP::load_class($name, $opts);
480 my $meta = Class::MOP::class_of($name);
481 $self->throw_error("You cannot inherit from a Moose Role ($name)")
e2eef3a5 482 if $meta && $meta->isa('Moose::Meta::Role')
483 }
2e7f6cf4 484 return $self->SUPER::superclasses(map { $_->[0] } @{ $supers });
e2eef3a5 485}
486
093b12c2 487### ---------------------------------------------
488
a2eec5e7 489sub add_attribute {
490 my $self = shift;
28af3424 491 my $attr =
e472c9a5 492 (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
d03bd989 493 ? $_[0]
28af3424 494 : $self->_process_attribute(@_));
495 $self->SUPER::add_attribute($attr);
496 # it may be a Class::MOP::Attribute, theoretically, which doesn't have
497 # 'bare' and doesn't implement this method
9340e346 498 if ($attr->can('_check_associated_methods')) {
499 $attr->_check_associated_methods;
28af3424 500 }
501 return $attr;
a2eec5e7 502}
503
78cd1d3b 504sub add_override_method_modifier {
505 my ($self, $name, $method, $_super_package) = @_;
18c2ec0e 506
d05cd563 507 (!$self->has_method($name))
11c86f15 508 || $self->throw_error("Cannot add an override method if a local method is already present");
18c2ec0e 509
74862722 510 $self->add_method($name => Moose::Meta::Method::Overridden->new(
3f9e4b0a 511 method => $method,
512 class => $self,
513 package => $_super_package, # need this for roles
514 name => $name,
18c2ec0e 515 ));
78cd1d3b 516}
517
518sub add_augment_method_modifier {
ac2dc464 519 my ($self, $name, $method) = @_;
d05cd563 520 (!$self->has_method($name))
11c86f15 521 || $self->throw_error("Cannot add an augment method if a local method is already present");
3f9e4b0a 522
523 $self->add_method($name => Moose::Meta::Method::Augmented->new(
524 method => $method,
525 class => $self,
526 name => $name,
527 ));
78cd1d3b 528}
529
1341f10c 530## Private Utility methods ...
531
05d9eaf6 532sub _find_next_method_by_name_which_is_not_overridden {
533 my ($self, $name) = @_;
68efb014 534 foreach my $method ($self->find_all_methods_by_name($name)) {
ac2dc464 535 return $method->{code}
74862722 536 if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
05d9eaf6 537 }
538 return undef;
539}
540
f6df97ae 541## Metaclass compatibility
f8b6827f 542
f6df97ae 543sub _base_metaclasses {
544 my $self = shift;
545 my %metaclasses = $self->SUPER::_base_metaclasses;
546 for my $class (keys %metaclasses) {
547 $metaclasses{$class} =~ s/^Class::MOP/Moose::Meta/;
1341f10c 548 }
f6df97ae 549 return (
550 %metaclasses,
551 error_class => 'Moose::Error::Default',
f8b6827f 552 );
f8b6827f 553}
554
f6df97ae 555sub _fix_class_metaclass_incompatibility {
556 my $self = shift;
557 my ($super_meta) = @_;
f8b6827f 558
f6df97ae 559 $self->SUPER::_fix_class_metaclass_incompatibility(@_);
f8b6827f 560
88f2e008 561 if ($self->_class_metaclass_can_be_made_compatible($super_meta)) {
590e8894 562 ($self->is_pristine)
563 || confess "Can't fix metaclass incompatibility for "
564 . $self->name
565 . " because it is not pristine.";
a907317a 566 my $super_meta_name = $super_meta->_real_ref_name;
61907a02 567 my $class_meta_subclass_meta_name = Moose::Util::_reconcile_roles_for_metaclass(blessed($self), $super_meta_name);
8450b001 568 my $new_self = $class_meta_subclass_meta_name->reinitialize(
cf7febc7 569 $self->name,
570 );
6a52b083 571
8450b001 572 $self->_replace_self( $new_self, $class_meta_subclass_meta_name );
f8b6827f 573 }
f6df97ae 574}
f8b6827f 575
f6df97ae 576sub _fix_single_metaclass_incompatibility {
577 my $self = shift;
578 my ($metaclass_type, $super_meta) = @_;
f8b6827f 579
f6df97ae 580 $self->SUPER::_fix_single_metaclass_incompatibility(@_);
f8b6827f 581
88f2e008 582 if ($self->_single_metaclass_can_be_made_compatible($super_meta, $metaclass_type)) {
590e8894 583 ($self->is_pristine)
584 || confess "Can't fix metaclass incompatibility for "
585 . $self->name
586 . " because it is not pristine.";
7f6c8567 587 my $super_meta_name = $super_meta->_real_ref_name;
61907a02 588 my $class_specific_meta_subclass_meta_name = Moose::Util::_reconcile_roles_for_metaclass($self->$metaclass_type, $super_meta->$metaclass_type);
cf7febc7 589 my $new_self = $super_meta->reinitialize(
590 $self->name,
8450b001 591 $metaclass_type => $class_specific_meta_subclass_meta_name,
cf7febc7 592 );
6a52b083 593
7f6c8567 594 $self->_replace_self( $new_self, $super_meta_name );
f6df97ae 595 }
f8b6827f 596}
597
6a52b083 598sub _replace_self {
599 my $self = shift;
600 my ( $new_self, $new_class) = @_;
601
602 %$self = %$new_self;
603 bless $self, $new_class;
604
605 # We need to replace the cached metaclass instance or else when it goes
606 # out of scope Class::MOP::Class destroy's the namespace for the
607 # metaclass's class, causing much havoc.
dcc8dc06 608 my $weaken = Class::MOP::metaclass_is_weak( $self->name );
6a52b083 609 Class::MOP::store_metaclass_by_name( $self->name, $self );
dcc8dc06 610 Class::MOP::weaken_metaclass( $self->name ) if $weaken;
6a52b083 611}
612
1341f10c 613sub _process_attribute {
a3738e5b 614 my ( $self, $name, @args ) = @_;
7e59b803 615
616 @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
d9bb6c63 617
f9b5f5f8 618 if (($name || '') =~ /^\+(.*)/) {
7e59b803 619 return $self->_process_inherited_attribute($1, @args);
1341f10c 620 }
621 else {
7e59b803 622 return $self->_process_new_attribute($name, @args);
623 }
624}
625
626sub _process_new_attribute {
627 my ( $self, $name, @args ) = @_;
7e59b803 628
d5c30e52 629 $self->attribute_metaclass->interpolate_class_and_new($name, @args);
1341f10c 630}
631
632sub _process_inherited_attribute {
633 my ($self, $attr_name, %options) = @_;
634 my $inherited_attr = $self->find_attribute_by_name($attr_name);
635 (defined $inherited_attr)
329c5dd4 636 || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
1341f10c 637 if ($inherited_attr->isa('Moose::Meta::Attribute')) {
d7d8a8c7 638 return $inherited_attr->clone_and_inherit_options(%options);
1341f10c 639 }
640 else {
641 # NOTE:
642 # kind of a kludge to handle Class::MOP::Attributes
d7d8a8c7 643 return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
ac2dc464 644 }
1341f10c 645}
646
17c594b1 647# reinitialization support
648
649sub _restore_metaobjects_from {
650 my $self = shift;
651 my ($old_meta) = @_;
652
653 $self->SUPER::_restore_metaobjects_from($old_meta);
654
655 for my $role ( @{ $old_meta->roles } ) {
656 $self->add_role($role);
657 }
658
659 for my $application ( @{ $old_meta->_get_role_applications } ) {
660 $application->class($self);
661 $self->add_role_application ($application);
662 }
663}
664
948cd189 665## Immutability
666
667sub _immutable_options {
668 my ( $self, @args ) = @_;
669
670 $self->SUPER::_immutable_options(
671 inline_destructor => 1,
948cd189 672
673 # Moose always does this when an attribute is created
674 inline_accessors => 0,
675
676 @args,
677 );
678}
679
5cf3dbcf 680## -------------------------------------------------
681
bf6fa6b3 682our $error_level;
11c86f15 683
684sub throw_error {
685 my ( $self, @args ) = @_;
bf6fa6b3 686 local $error_level = ($error_level || 0) + 1;
11c86f15 687 $self->raise_error($self->create_error(@args));
688}
689
e3225a0f 690sub _inline_throw_error {
691 my ( $self, $msg, $args ) = @_;
692 "\$meta->throw_error($msg" . ($args ? ", $args" : "") . ")"; # FIXME makes deparsing *REALLY* hard
693}
694
11c86f15 695sub raise_error {
696 my ( $self, @args ) = @_;
697 die @args;
698}
699
700sub create_error {
701 my ( $self, @args ) = @_;
702
18748ad6 703 require Carp::Heavy;
704
bf6fa6b3 705 local $error_level = ($error_level || 0 ) + 1;
18748ad6 706
11c86f15 707 if ( @args % 2 == 1 ) {
708 unshift @args, "message";
709 }
710
fcab1742 711 my %args = ( metaclass => $self, last_error => $@, @args );
11c86f15 712
bf6fa6b3 713 $args{depth} += $error_level;
11c86f15 714
bf6fa6b3 715 my $class = ref $self ? $self->error_class : "Moose::Error::Default";
11c86f15 716
a810a01f 717 Class::MOP::load_class($class);
718
11c86f15 719 $class->new(
bf6fa6b3 720 Carp::caller_info($args{depth}),
721 %args
11c86f15 722 );
723}
724
c0e30cf5 7251;
726
ad46f524 727# ABSTRACT: The Moose metaclass
728
c0e30cf5 729__END__
730
731=pod
732
c0e30cf5 733=head1 DESCRIPTION
734
70bb0f97 735This class is a subclass of L<Class::MOP::Class> that provides
736additional Moose-specific functionality.
e522431d 737
7854b409 738To really understand this class, you will need to start with the
739L<Class::MOP::Class> documentation. This class can be understood as a
740set of additional features on top of the basic feature provided by
741that parent class.
6ba6d68c 742
d4b1449e 743=head1 INHERITANCE
744
745C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
746
c0e30cf5 747=head1 METHODS
748
749=over 4
750
70bb0f97 751=item B<< Moose::Meta::Class->initialize($package_name, %options) >>
590868a3 752
70bb0f97 753This overrides the parent's method in order to provide its own
754defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
755C<method_metaclass> options.
61bdd94f 756
70bb0f97 757These all default to the appropriate Moose class.
61bdd94f 758
70bb0f97 759=item B<< Moose::Meta::Class->create($package_name, %options) >>
17594769 760
70bb0f97 761This overrides the parent's method in order to accept a C<roles>
9e25a72a 762option. This should be an array reference containing roles
763that the class does, each optionally followed by a hashref of options
764(C<-excludes> and C<-alias>).
17594769 765
70bb0f97 766 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
17594769 767
70bb0f97 768=item B<< Moose::Meta::Class->create_anon_class >>
17594769 769
70bb0f97 770This overrides the parent's method to accept a C<roles> option, just
771as C<create> does.
5cf3dbcf 772
70bb0f97 773It also accepts a C<cache> option. If this is true, then the anonymous
774class will be cached based on its superclasses and roles. If an
775existing anonymous class in the cache has the same superclasses and
776roles, it will be reused.
ac2dc464 777
70bb0f97 778 my $metaclass = Moose::Meta::Class->create_anon_class(
779 superclasses => ['Foo'],
780 roles => [qw/Some Roles Go Here/],
781 cache => 1,
782 );
ac2dc464 783
2e7f6cf4 784Each entry in both the C<superclasses> and the C<roles> option can be
b2d54db8 785followed by a hash reference with arguments. The C<superclasses>
2e7f6cf4 786option can be supplied with a L<-version|Class::MOP/Class Loading
787Options> option that ensures the loaded superclass satisfies the
788required version. The C<role> option also takes the C<-version> as an
789argument, but the option hash reference can also contain any other
790role relevant values like exclusions or parameterized role arguments.
791
70bb0f97 792=item B<< $metaclass->make_immutable(%options) >>
ac2dc464 793
70bb0f97 794This overrides the parent's method to add a few options. Specifically,
795it uses the Moose-specific constructor and destructor classes, and
796enables inlining the destructor.
8c9d74e7 797
dcdceb38 798Since Moose always inlines attributes, it sets the C<inline_accessors> option
799to false.
800
70bb0f97 801=item B<< $metaclass->new_object(%params) >>
a15dff8d 802
70bb0f97 803This overrides the parent's method in order to add support for
804attribute triggers.
6ba6d68c 805
2e7f6cf4 806=item B<< $metaclass->superclasses(@superclasses) >>
807
6b958a3e 808This is the accessor allowing you to read or change the parents of
2e7f6cf4 809the class.
810
811Each superclass can be followed by a hash reference containing a
812L<-version|Class::MOP/Class Loading Options> value. If the version
813requirement is not satisfied an error will be thrown.
814
70bb0f97 815=item B<< $metaclass->add_override_method_modifier($name, $sub) >>
ef1d5f4b 816
70bb0f97 817This adds an C<override> method modifier to the package.
e9ec68d6 818
70bb0f97 819=item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
e9ec68d6 820
70bb0f97 821This adds an C<augment> method modifier to the package.
78cd1d3b 822
70bb0f97 823=item B<< $metaclass->calculate_all_roles >>
02a0fb52 824
70bb0f97 825This will return a unique array of C<Moose::Meta::Role> instances
826which are attached to this class.
78cd1d3b 827
9f83eb5d 828=item B<< $metaclass->calculate_all_roles_with_inheritance >>
829
830This will return a unique array of C<Moose::Meta::Role> instances
831which are attached to this class, and each of this class's ancestors.
832
70bb0f97 833=item B<< $metaclass->add_role($role) >>
02a0fb52 834
70bb0f97 835This takes a L<Moose::Meta::Role> object, and adds it to the class's
836list of roles. This I<does not> actually apply the role to the class.
2b14ac61 837
b90dd4ef 838=item B<< $metaclass->role_applications >>
839
639f9a1a 840Returns a list of L<Moose::Meta::Role::Application::ToClass>
b90dd4ef 841objects, which contain the arguments to role application.
842
843=item B<< $metaclass->add_role_application($application) >>
844
845This takes a L<Moose::Meta::Role::Application::ToClass> object, and
846adds it to the class's list of role applications. This I<does not>
847actually apply any role to the class; it is only for tracking role
848applications.
849
560c498d 850=item B<< $metaclass->does_role($role) >>
ef333f17 851
560c498d 852This returns a boolean indicating whether or not the class does the specified
853role. The role provided can be either a role name or a L<Moose::Meta::Role>
854object. This tests both the class and its parents.
02a0fb52 855
70bb0f97 856=item B<< $metaclass->excludes_role($role_name) >>
ef333f17 857
70bb0f97 858A class excludes a role if it has already composed a role which
859excludes the named role. This tests both the class and its parents.
02a0fb52 860
70bb0f97 861=item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
ef333f17 862
70bb0f97 863This overrides the parent's method in order to allow the parameters to
864be provided as a hash reference.
02a0fb52 865
9f9fdd08 866=item B<< $metaclass->constructor_class($class_name) >>
d79e62fd 867
9f9fdd08 868=item B<< $metaclass->destructor_class($class_name) >>
e606ae5f 869
948cd189 870These are the names of classes used when making a class immutable. These
90a49845 871default to L<Moose::Meta::Method::Constructor> and
872L<Moose::Meta::Method::Destructor> respectively. These accessors are
873read-write, so you can use them to change the class name.
e606ae5f 874
70bb0f97 875=item B<< $metaclass->error_class($class_name) >>
8b1d510f 876
70bb0f97 877The name of the class used to throw errors. This defaults to
8b1d510f 878L<Moose::Error::Default>, which generates an error with a stacktrace
879just like C<Carp::confess>.
880
70bb0f97 881=item B<< $metaclass->throw_error($message, %extra) >>
11c86f15 882
883Throws the error created by C<create_error> using C<raise_error>
884
c0e30cf5 885=back
886
887=head1 BUGS
888
d4048ef3 889See L<Moose/BUGS> for details on reporting bugs.
c0e30cf5 890
8a7a9c53 891=cut
1a563243 892