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