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