Add note about conflict list
[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
11c86f15 9use Carp ();
f8b6827f 10use List::Util qw( first );
11use List::MoreUtils qw( any all );
21f1e231 12use Scalar::Util 'weaken', 'blessed';
a15dff8d 13
e606ae5f 14our $VERSION = '0.57';
15$VERSION = eval $VERSION;
d44714be 16our $AUTHORITY = 'cpan:STEVAN';
bc1e29b5 17
8ee73eeb 18use Moose::Meta::Method::Overriden;
3f9e4b0a 19use Moose::Meta::Method::Augmented;
8ee73eeb 20
c0e30cf5 21use base 'Class::MOP::Class';
22
598340d5 23__PACKAGE__->meta->add_attribute('roles' => (
ef333f17 24 reader => 'roles',
25 default => sub { [] }
26));
27
e606ae5f 28__PACKAGE__->meta->add_attribute('constructor_class' => (
29 accessor => 'constructor_class',
30 default => sub { 'Moose::Meta::Method::Constructor' }
31));
32
33__PACKAGE__->meta->add_attribute('destructor_class' => (
34 accessor => 'destructor_class',
35 default => sub { 'Moose::Meta::Method::Destructor' }
36));
37
11c86f15 38__PACKAGE__->meta->add_attribute('error_builder' => (
39 reader => 'error_builder',
40 default => 'confess',
41));
42
43__PACKAGE__->meta->add_attribute('error_class' => (
44 reader => 'error_class',
45));
46
47
590868a3 48sub initialize {
49 my $class = shift;
50 my $pkg = shift;
685f7e44 51 return Class::MOP::get_metaclass_by_name($pkg)
52 || $class->SUPER::initialize($pkg,
53 'attribute_metaclass' => 'Moose::Meta::Attribute',
54 'method_metaclass' => 'Moose::Meta::Method',
55 'instance_metaclass' => 'Moose::Meta::Instance',
56 @_
57 );
ac2dc464 58}
590868a3 59
61bdd94f 60sub create {
61 my ($self, $package_name, %options) = @_;
62
63 (ref $options{roles} eq 'ARRAY')
11c86f15 64 || $self->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
61bdd94f 65 if exists $options{roles};
dd37a5be 66
61bdd94f 67 my $class = $self->SUPER::create($package_name, %options);
dd37a5be 68
48045612 69 if (exists $options{roles}) {
61bdd94f 70 Moose::Util::apply_all_roles($class, @{$options{roles}});
71 }
72
73 return $class;
74}
75
2b72f3b4 76sub check_metaclass_compatibility {
77 my $self = shift;
78
79 if ( my @supers = $self->superclasses ) {
80 $self->_fix_metaclass_incompatibility(@supers);
81 }
82
83 $self->SUPER::check_metaclass_compatibility(@_);
84}
85
17594769 86my %ANON_CLASSES;
87
88sub create_anon_class {
89 my ($self, %options) = @_;
90
91 my $cache_ok = delete $options{cache};
17594769 92
93 # something like Super::Class|Super::Class::2=Role|Role::1
94 my $cache_key = join '=' => (
6d5cbd2b 95 join('|', sort @{$options{superclasses} || []}),
96 join('|', sort @{$options{roles} || []}),
17594769 97 );
98
6d5cbd2b 99 if ($cache_ok && defined $ANON_CLASSES{$cache_key}) {
17594769 100 return $ANON_CLASSES{$cache_key};
101 }
102
103 my $new_class = $self->SUPER::create_anon_class(%options);
104
6d5cbd2b 105 $ANON_CLASSES{$cache_key} = $new_class
106 if $cache_ok;
17594769 107
108 return $new_class;
109}
110
ef333f17 111sub add_role {
112 my ($self, $role) = @_;
113 (blessed($role) && $role->isa('Moose::Meta::Role'))
11c86f15 114 || $self->throw_error("Roles must be instances of Moose::Meta::Role", data => $role);
ef333f17 115 push @{$self->roles} => $role;
116}
117
b8aeb4dc 118sub calculate_all_roles {
119 my $self = shift;
120 my %seen;
121 grep { !$seen{$_->name}++ } map { $_->calculate_all_roles } @{ $self->roles };
122}
123
ef333f17 124sub does_role {
125 my ($self, $role_name) = @_;
126 (defined $role_name)
11c86f15 127 || $self->throw_error("You must supply a role name to look for");
9c429218 128 foreach my $class ($self->class_precedence_list) {
81c3738f 129 next unless $class->can('meta') && $class->meta->can('roles');
9c429218 130 foreach my $role (@{$class->meta->roles}) {
131 return 1 if $role->does_role($role_name);
132 }
ef333f17 133 }
134 return 0;
135}
136
d79e62fd 137sub excludes_role {
138 my ($self, $role_name) = @_;
139 (defined $role_name)
11c86f15 140 || $self->throw_error("You must supply a role name to look for");
ac2dc464 141 foreach my $class ($self->class_precedence_list) {
142 next unless $class->can('meta');
5cb193ed 143 # NOTE:
144 # in the pretty rare instance when a Moose metaclass
ac2dc464 145 # is itself extended with a role, this check needs to
5cb193ed 146 # be done since some items in the class_precedence_list
ac2dc464 147 # might in fact be Class::MOP based still.
148 next unless $class->meta->can('roles');
9c429218 149 foreach my $role (@{$class->meta->roles}) {
150 return 1 if $role->excludes_role($role_name);
151 }
d79e62fd 152 }
153 return 0;
154}
155
8c9d74e7 156sub new_object {
e606ae5f 157 my $class = shift;
158 my $params = @_ == 1 ? $_[0] : {@_};
159 my $self = $class->SUPER::new_object($params);
8c9d74e7 160 foreach my $attr ($class->compute_all_applicable_attributes()) {
4078709c 161 # if we have a trigger, then ...
162 if ($attr->can('has_trigger') && $attr->has_trigger) {
163 # make sure we have an init-arg ...
164 if (defined(my $init_arg = $attr->init_arg)) {
165 # now make sure an init-arg was passes ...
e606ae5f 166 if (exists $params->{$init_arg}) {
4078709c 167 # and if get here, fire the trigger
168 $attr->trigger->(
169 $self,
170 # check if there is a coercion
171 ($attr->should_coerce
172 # and if so, we need to grab the
173 # value that is actually been stored
174 ? $attr->get_read_method_ref->($self)
175 # otherwise, just get the value from
176 # the constructor params
e606ae5f 177 : $params->{$init_arg}),
4078709c 178 $attr
179 );
180 }
181 }
625d571f 182 }
8c9d74e7 183 }
ac2dc464 184 return $self;
8c9d74e7 185}
186
a15dff8d 187sub construct_instance {
e606ae5f 188 my $class = shift;
189 my $params = @_ == 1 ? $_[0] : {@_};
ddd0ec20 190 my $meta_instance = $class->get_meta_instance;
575db57d 191 # FIXME:
192 # the code below is almost certainly incorrect
193 # but this is foreign inheritence, so we might
ac2dc464 194 # have to kludge it in the end.
e606ae5f 195 my $instance = $params->{'__INSTANCE__'} || $meta_instance->create_instance();
ac2dc464 196 foreach my $attr ($class->compute_all_applicable_attributes()) {
e606ae5f 197 $attr->initialize_instance_slot($meta_instance, $instance, $params);
a15dff8d 198 }
199 return $instance;
200}
201
093b12c2 202# FIXME:
203# This is ugly
ac2dc464 204sub get_method_map {
093b12c2 205 my $self = shift;
53dd42d8 206
e606ae5f 207 my $current = Class::MOP::check_package_cache_flag($self->name);
208
209 if (defined $self->{'_package_cache_flag'} && $self->{'_package_cache_flag'} == $current) {
210 return $self->{'methods'};
53dd42d8 211 }
212
e606ae5f 213 $self->{_package_cache_flag} = $current;
214
215 my $map = $self->{'methods'};
ac2dc464 216
093b12c2 217 my $class_name = $self->name;
218 my $method_metaclass = $self->method_metaclass;
ac2dc464 219
0addec44 220 my %all_code = $self->get_all_package_symbols('CODE');
ac2dc464 221
0addec44 222 foreach my $symbol (keys %all_code) {
223 my $code = $all_code{$symbol};
ac2dc464 224
225 next if exists $map->{$symbol} &&
226 defined $map->{$symbol} &&
227 $map->{$symbol}->body == $code;
228
53dd42d8 229 my ($pkg, $name) = Class::MOP::get_code_info($code);
ac2dc464 230
53dd42d8 231 if ($pkg->can('meta')
4f8f3aab 232 # NOTE:
233 # we don't know what ->meta we are calling
53dd42d8 234 # here, so we need to be careful cause it
235 # just might blow up at us, or just complain
236 # loudly (in the case of Curses.pm) so we
4f8f3aab 237 # just be a little overly cautious here.
238 # - SL
239 && eval { no warnings; blessed($pkg->meta) }
240 && $pkg->meta->isa('Moose::Meta::Role')) {
093b12c2 241 #my $role = $pkg->meta->name;
242 #next unless $self->does_role($role);
243 }
244 else {
2887c827 245
246 # NOTE:
247 # in 5.10 constant.pm the constants show up
248 # as being in the right package, but in pre-5.10
249 # they show up as constant::__ANON__ so we
250 # make an exception here to be sure that things
251 # work as expected in both.
252 # - SL
253 unless ($pkg eq 'constant' && $name eq '__ANON__') {
254 next if ($pkg || '') ne $class_name ||
255 (($name || '') ne '__ANON__' && ($pkg || '') ne $class_name);
256 }
53dd42d8 257
093b12c2 258 }
ac2dc464 259
1b2aea39 260 $map->{$symbol} = $method_metaclass->wrap(
261 $code,
262 package_name => $class_name,
263 name => $symbol
264 );
093b12c2 265 }
ac2dc464 266
093b12c2 267 return $map;
a7d0cd00 268}
269
093b12c2 270### ---------------------------------------------
271
a2eec5e7 272sub add_attribute {
273 my $self = shift;
e472c9a5 274 $self->SUPER::add_attribute(
275 (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
276 ? $_[0]
277 : $self->_process_attribute(@_))
278 );
a2eec5e7 279}
280
78cd1d3b 281sub add_override_method_modifier {
282 my ($self, $name, $method, $_super_package) = @_;
18c2ec0e 283
d05cd563 284 (!$self->has_method($name))
11c86f15 285 || $self->throw_error("Cannot add an override method if a local method is already present");
18c2ec0e 286
287 $self->add_method($name => Moose::Meta::Method::Overriden->new(
3f9e4b0a 288 method => $method,
289 class => $self,
290 package => $_super_package, # need this for roles
291 name => $name,
18c2ec0e 292 ));
78cd1d3b 293}
294
295sub add_augment_method_modifier {
ac2dc464 296 my ($self, $name, $method) = @_;
d05cd563 297 (!$self->has_method($name))
11c86f15 298 || $self->throw_error("Cannot add an augment method if a local method is already present");
3f9e4b0a 299
300 $self->add_method($name => Moose::Meta::Method::Augmented->new(
301 method => $method,
302 class => $self,
303 name => $name,
304 ));
78cd1d3b 305}
306
1341f10c 307## Private Utility methods ...
308
05d9eaf6 309sub _find_next_method_by_name_which_is_not_overridden {
310 my ($self, $name) = @_;
68efb014 311 foreach my $method ($self->find_all_methods_by_name($name)) {
ac2dc464 312 return $method->{code}
05d9eaf6 313 if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overriden');
314 }
315 return undef;
316}
317
41419b9e 318sub _fix_metaclass_incompatibility {
1341f10c 319 my ($self, @superclasses) = @_;
e606ae5f 320
1341f10c 321 foreach my $super (@superclasses) {
f8b6827f 322 next if $self->_superclass_meta_is_compatible($super);
e606ae5f 323
324 unless ( $self->is_pristine ) {
f8b6827f 325 $self->throw_error(
326 "Cannot attempt to reinitialize metaclass for "
327 . $self->name
328 . ", it isn't pristine" );
1341f10c 329 }
e606ae5f 330
0635500e 331 $self->_reconcile_with_superclass_meta($super);
f8b6827f 332 }
f8b6827f 333}
334
335sub _superclass_meta_is_compatible {
336 my ($self, $super) = @_;
337
338 my $super_meta = Class::MOP::Class->initialize($super)
339 or return 1;
340
341 next unless $super_meta->isa("Class::MOP::Class");
342
343 my $super_meta_name
344 = $super_meta->is_immutable
345 ? $super_meta->get_mutable_metaclass_name
346 : ref($super_meta);
347
348 return 1
349 if $self->isa($super_meta_name)
350 and
351 $self->instance_metaclass->isa( $super_meta->instance_metaclass );
352}
353
354# I don't want to have to type this >1 time
355my @MetaClassTypes =
356 qw( attribute_metaclass method_metaclass instance_metaclass constructor_class destructor_class );
357
358sub _reconcile_with_superclass_meta {
359 my ($self, $super) = @_;
360
361 my $super_meta = $super->meta;
362
dd37a5be 363 my $super_meta_name
f8b6827f 364 = $super_meta->is_immutable
365 ? $super_meta->get_mutable_metaclass_name
366 : ref($super_meta);
e606ae5f 367
f8b6827f 368 my $self_metaclass = ref $self;
369
370 # If neither of these is true we have a more serious
371 # incompatibility that we just cannot fix (yet?).
dd37a5be 372 if ( $super_meta_name->isa( ref $self )
f8b6827f 373 && all { $super_meta->$_->isa( $self->$_ ) } @MetaClassTypes ) {
0635500e 374 $self->_reinitialize_with($super_meta);
f8b6827f 375 }
376 elsif ( $self->_all_metaclasses_differ_by_roles_only($super_meta) ) {
0635500e 377 $self->_reconcile_role_differences($super_meta);
1341f10c 378 }
1341f10c 379}
380
f8b6827f 381sub _reinitialize_with {
382 my ( $self, $new_meta ) = @_;
383
0635500e 384 my $new_self = $new_meta->reinitialize(
f8b6827f 385 $self->name,
386 attribute_metaclass => $new_meta->attribute_metaclass,
387 method_metaclass => $new_meta->method_metaclass,
388 instance_metaclass => $new_meta->instance_metaclass,
389 );
390
0635500e 391 $new_self->$_( $new_meta->$_ ) for qw( constructor_class destructor_class );
f8b6827f 392
0635500e 393 %$self = %$new_self;
394
395 bless $self, ref $new_self;
396
4c5fcc12 397 # We need to replace the cached metaclass instance or else when it
398 # goes out of scope Class::MOP::Class destroy's the namespace for
399 # the metaclass's class, causing much havoc.
0635500e 400 Class::MOP::store_metaclass_by_name( $self->name, $self );
4c5fcc12 401 Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class;
f8b6827f 402}
403
404# In the more complex case, we share a common ancestor with our
405# superclass's metaclass, but each metaclass (ours and the parent's)
406# has a different set of roles applied. We reconcile this by first
407# reinitializing into the parent class, and _then_ applying our own
408# roles.
409sub _all_metaclasses_differ_by_roles_only {
410 my ($self, $super_meta) = @_;
411
412 for my $pair (
413 [ ref $self, ref $super_meta ],
414 map { [ $self->$_, $super_meta->$_ ] } @MetaClassTypes
415 ) {
416
417 next if $pair->[0] eq $pair->[1];
418
419 my $self_meta_meta = Class::MOP::Class->initialize( $pair->[0] );
420 my $super_meta_meta = Class::MOP::Class->initialize( $pair->[1] );
421
422 my $common_ancestor
423 = _find_common_ancestor( $self_meta_meta, $super_meta_meta );
424
425 return unless $common_ancestor;
426
427 return
428 unless _is_role_only_subclass_of(
429 $self_meta_meta,
430 $common_ancestor,
431 )
432 && _is_role_only_subclass_of(
433 $super_meta_meta,
434 $common_ancestor,
435 );
436 }
437
438 return 1;
439}
440
441# This, and some other functions, could be called as methods, but
442# they're not for two reasons. One, we just end up ignoring the first
443# argument, because we can't call these directly on one of the real
444# arguments, because one of them could be a Class::MOP::Class object
445# and not a Moose::Meta::Class. Second, only a completely insane
446# person would attempt to subclass this stuff!
447sub _find_common_ancestor {
448 my ($meta1, $meta2) = @_;
449
450 # FIXME? This doesn't account for multiple inheritance (not sure
451 # if it needs to though). For example, is somewhere in $meta1's
452 # history it inherits from both ClassA and ClassB, and $meta
453 # inherits from ClassB & ClassA, does it matter? And what crazy
454 # fool would do that anyway?
455
456 my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
457
458 return first { $meta1_parents{$_} } $meta2->linearized_isa;
459}
460
461sub _is_role_only_subclass_of {
462 my ($meta, $ancestor) = @_;
463
464 return 1 if $meta->name eq $ancestor;
465
466 my @roles = _all_roles_until( $meta, $ancestor );
467
468 my %role_packages = map { $_->name => 1 } @roles;
469
470 my $ancestor_meta = Class::MOP::Class->initialize($ancestor);
471
472 my %shared_ancestors = map { $_ => 1 } $ancestor_meta->linearized_isa;
473
474 for my $method ( $meta->get_all_methods() ) {
475 next if $method->name eq 'meta';
476 next if $method->can('associated_attribute');
477
478 next
479 if $role_packages{ $method->original_package_name }
480 || $shared_ancestors{ $method->original_package_name };
481
482 return 0;
483 }
484
485 # FIXME - this really isn't right. Just because an attribute is
486 # defined in a role doesn't mean it isn't _also_ defined in the
487 # subclass.
488 for my $attr ( $meta->get_all_attributes ) {
489 next if $shared_ancestors{ $attr->associated_class->name };
490
491 next if any { $_->has_attribute( $attr->name ) } @roles;
492
493 return 0;
494 }
495
496 return 1;
497}
498
499sub _all_roles {
500 my $meta = shift;
501
502 return _all_roles_until($meta);
503}
504
505sub _all_roles_until {
506 my ($meta, $stop_at_class) = @_;
507
508 return unless $meta->can('calculate_all_roles');
509
510 my @roles = $meta->calculate_all_roles;
511
512 for my $class ( $meta->linearized_isa ) {
513 last if $stop_at_class && $stop_at_class eq $class;
514
515 my $meta = Class::MOP::Class->initialize($class);
516 last unless $meta->can('calculate_all_roles');
517
518 push @roles, $meta->calculate_all_roles;
519 }
520
521 return @roles;
522}
523
524sub _reconcile_role_differences {
525 my ($self, $super_meta) = @_;
526
527 my $self_meta = $self->meta;
528
529 my %roles;
530
531 if ( my @roles = map { $_->name } _all_roles($self_meta) ) {
532 $roles{metaclass_roles} = \@roles;
533 }
534
535 for my $thing (@MetaClassTypes) {
536 my $name = $self->$thing();
537
538 my $thing_meta = Class::MOP::Class->initialize($name);
539
540 my @roles = map { $_->name } _all_roles($thing_meta)
541 or next;
542
543 $roles{ $thing . '_roles' } = \@roles;
544 }
545
2b72f3b4 546 $self->_reinitialize_with($super_meta);
f8b6827f 547
548 Moose::Util::MetaRole::apply_metaclass_roles(
549 for_class => $self->name,
550 %roles,
551 );
552
553 return $self;
554}
555
d7d8a8c7 556# NOTE:
d9bb6c63 557# this was crap anyway, see
558# Moose::Util::apply_all_roles
d7d8a8c7 559# instead
4498537c 560sub _apply_all_roles {
547dda77 561 Carp::croak 'DEPRECATED: use Moose::Util::apply_all_roles($meta, @roles) instead'
4498537c 562}
1341f10c 563
564sub _process_attribute {
a3738e5b 565 my ( $self, $name, @args ) = @_;
7e59b803 566
567 @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
d9bb6c63 568
1341f10c 569 if ($name =~ /^\+(.*)/) {
7e59b803 570 return $self->_process_inherited_attribute($1, @args);
1341f10c 571 }
572 else {
7e59b803 573 return $self->_process_new_attribute($name, @args);
574 }
575}
576
577sub _process_new_attribute {
578 my ( $self, $name, @args ) = @_;
7e59b803 579
d5c30e52 580 $self->attribute_metaclass->interpolate_class_and_new($name, @args);
1341f10c 581}
582
583sub _process_inherited_attribute {
584 my ($self, $attr_name, %options) = @_;
585 my $inherited_attr = $self->find_attribute_by_name($attr_name);
586 (defined $inherited_attr)
11c86f15 587 || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from", data => $attr_name);
1341f10c 588 if ($inherited_attr->isa('Moose::Meta::Attribute')) {
d7d8a8c7 589 return $inherited_attr->clone_and_inherit_options(%options);
1341f10c 590 }
591 else {
592 # NOTE:
593 # kind of a kludge to handle Class::MOP::Attributes
d7d8a8c7 594 return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
ac2dc464 595 }
1341f10c 596}
597
5cf3dbcf 598## -------------------------------------------------
599
600use Moose::Meta::Method::Constructor;
1f779926 601use Moose::Meta::Method::Destructor;
5cf3dbcf 602
ac2dc464 603# This could be done by using SUPER and altering ->options
604# I am keeping it this way to make it more explicit.
605sub create_immutable_transformer {
606 my $self = shift;
607 my $class = Class::MOP::Immutable->new($self, {
e606ae5f 608 read_only => [qw/superclasses/],
609 cannot_call => [qw/
610 add_method
611 alias_method
612 remove_method
613 add_attribute
614 remove_attribute
615 remove_package_symbol
616 add_role
617 /],
618 memoize => {
619 class_precedence_list => 'ARRAY',
620 linearized_isa => 'ARRAY', # FIXME perl 5.10 memoizes this on its own, no need?
621 get_all_methods => 'ARRAY',
622 #get_all_attributes => 'ARRAY', # it's an alias, no need, but maybe in the future
623 compute_all_applicable_attributes => 'ARRAY',
624 get_meta_instance => 'SCALAR',
625 get_method_map => 'SCALAR',
626 calculate_all_roles => 'ARRAY',
627 },
628 # NOTE:
629 # this is ugly, but so are typeglobs,
630 # so whattayahgonnadoboutit
631 # - SL
632 wrapped => {
633 add_package_symbol => sub {
634 my $original = shift;
635 $self->throw_error("Cannot add package symbols to an immutable metaclass")
636 unless (caller(2))[3] eq 'Class::MOP::Package::get_package_symbol';
637 goto $original->body;
638 },
639 },
ac2dc464 640 });
641 return $class;
642}
643
644sub make_immutable {
645 my $self = shift;
646 $self->SUPER::make_immutable
647 (
e606ae5f 648 constructor_class => $self->constructor_class,
649 destructor_class => $self->destructor_class,
ac2dc464 650 inline_destructor => 1,
651 # NOTE:
652 # no need to do this,
653 # Moose always does it
654 inline_accessors => 0,
655 @_,
656 );
5cf3dbcf 657}
658
11c86f15 659#{ package Moose::Meta::Class::ErrorRoutines; %Carp::Internal?
660
661our $level;
662
663sub throw_error {
664 my ( $self, @args ) = @_;
665 local $level = 1;
666 $self->raise_error($self->create_error(@args));
667}
668
669sub raise_error {
670 my ( $self, @args ) = @_;
671 die @args;
672}
673
674sub create_error {
675 my ( $self, @args ) = @_;
676
677 if ( @args % 2 == 1 ) {
678 unshift @args, "message";
679 }
680
be05faea 681 my %args = ( meta => $self, error => $@, @args );
11c86f15 682
683 local $level = $level + 1;
684
685 if ( my $class = $args{class} || ( ref $self && $self->error_class ) ) {
686 return $self->create_error_object( %args, class => $class );
687 } else {
688 my $builder = $args{builder} || ( ref($self) ? $self->error_builder : "confess" );
689
690 my $builder_method = ( ( ref($builder) && ref($builder) eq 'CODE' )
691 ? $builder
692 : ( $self->can("create_error_$builder") || "create_error_confess" ));
693
694 return $self->$builder_method(%args);
695 }
696}
697
698sub create_error_object {
699 my ( $self, %args ) = @_;
700
701 my $class = delete $args{class};
702
703 $class->new(
11c86f15 704 %args,
705 depth => ( ($args{depth} || 1) + ( $level + 1 ) ),
706 );
707}
708
709sub create_error_croak {
710 my ( $self, @args ) = @_;
711 $self->_create_error_carpmess( @args );
712}
713
714sub create_error_confess {
715 my ( $self, @args ) = @_;
716 $self->_create_error_carpmess( @args, longmess => 1 );
717}
718
719sub _create_error_carpmess {
720 my ( $self, %args ) = @_;
721
722 my $carp_level = $level + 1 + ( $args{depth} || 1 );
723
724 local $Carp::CarpLevel = $carp_level; # $Carp::CarpLevel + $carp_level ?
725 local $Carp::MaxArgNums = 20; # default is 8, usually we use named args which gets messier though
726
727 my @args = exists $args{message} ? $args{message} : ();
728
729 if ( $args{longmess} ) {
730 return Carp::longmess(@args);
731 } else {
732 return Carp::shortmess(@args);
733 }
734}
735
c0e30cf5 7361;
737
738__END__
739
740=pod
741
742=head1 NAME
743
e522431d 744Moose::Meta::Class - The Moose metaclass
c0e30cf5 745
c0e30cf5 746=head1 DESCRIPTION
747
ac2dc464 748This is a subclass of L<Class::MOP::Class> with Moose specific
e522431d 749extensions.
750
ac2dc464 751For the most part, the only time you will ever encounter an
752instance of this class is if you are doing some serious deep
753introspection. To really understand this class, you need to refer
6ba6d68c 754to the L<Class::MOP::Class> documentation.
755
c0e30cf5 756=head1 METHODS
757
758=over 4
759
590868a3 760=item B<initialize>
761
61bdd94f 762=item B<create>
763
17594769 764Overrides original to accept a list of roles to apply to
61bdd94f 765the created class.
766
17594769 767 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
768
769=item B<create_anon_class>
770
771Overrides original to support roles and caching.
772
773 my $metaclass = Moose::Meta::Class->create_anon_class(
774 superclasses => ['Foo'],
775 roles => [qw/Some Roles Go Here/],
776 cache => 1,
777 );
778
5cf3dbcf 779=item B<make_immutable>
780
ac2dc464 781Override original to add default options for inlining destructor
782and altering the Constructor metaclass.
783
784=item B<create_immutable_transformer>
785
786Override original to lock C<add_role> and memoize C<calculate_all_roles>
787
8c9d74e7 788=item B<new_object>
789
02a0fb52 790We override this method to support the C<trigger> attribute option.
791
a15dff8d 792=item B<construct_instance>
793
ac2dc464 794This provides some Moose specific extensions to this method, you
795almost never call this method directly unless you really know what
796you are doing.
6ba6d68c 797
798This method makes sure to handle the moose weak-ref, type-constraint
ac2dc464 799and type coercion features.
ef1d5f4b 800
093b12c2 801=item B<get_method_map>
e9ec68d6 802
ac2dc464 803This accommodates Moose::Meta::Role::Method instances, which are
804aliased, instead of added, but still need to be counted as valid
e9ec68d6 805methods.
806
78cd1d3b 807=item B<add_override_method_modifier ($name, $method)>
808
ac2dc464 809This will create an C<override> method modifier for you, and install
02a0fb52 810it in the package.
811
78cd1d3b 812=item B<add_augment_method_modifier ($name, $method)>
813
ac2dc464 814This will create an C<augment> method modifier for you, and install
02a0fb52 815it in the package.
816
2b14ac61 817=item B<calculate_all_roles>
818
ef333f17 819=item B<roles>
820
ac2dc464 821This will return an array of C<Moose::Meta::Role> instances which are
02a0fb52 822attached to this class.
823
ef333f17 824=item B<add_role ($role)>
825
ac2dc464 826This takes an instance of C<Moose::Meta::Role> in C<$role>, and adds it
02a0fb52 827to the list of associated roles.
828
ef333f17 829=item B<does_role ($role_name)>
830
ac2dc464 831This will test if this class C<does> a given C<$role_name>. It will
832not only check it's local roles, but ask them as well in order to
02a0fb52 833cascade down the role hierarchy.
834
d79e62fd 835=item B<excludes_role ($role_name)>
836
ac2dc464 837This will test if this class C<excludes> a given C<$role_name>. It will
838not only check it's local roles, but ask them as well in order to
d79e62fd 839cascade down the role hierarchy.
840
9e93dd19 841=item B<add_attribute ($attr_name, %params|$params)>
4e848edb 842
9e93dd19 843This method does the same thing as L<Class::MOP::Class::add_attribute>, but adds
844support for taking the C<$params> as a HASH ref.
ac1ef2f9 845
e606ae5f 846=item B<constructor_class ($class_name)>
847
848=item B<destructor_class ($class_name)>
849
850These are the names of classes used when making a class
851immutable. These default to L<Moose::Meta::Method::Constructor> and
852L<Moose::Meta::Method::Destructor> respectively. These accessors are
853read-write, so you can use them to change the class name.
854
4fb87686 855=item B<check_metaclass_compatibility>
856
857Moose overrides this method from C<Class::MOP::Class> and attempts to
858fix some incompatibilities before doing the check.
859
11c86f15 860=item B<throw_error $message, %extra>
861
862Throws the error created by C<create_error> using C<raise_error>
863
864=item B<create_error $message, %extra>
865
866Creates an error message or object.
867
868The default behavior is C<create_error_confess>.
869
870If C<error_class> is set uses C<create_error_object>. Otherwise uses
871C<error_builder> (a code reference or variant name), and calls the appropriate
872C<create_error_$builder> method.
873
874=item B<error_builder $builder_name>
875
876Get or set the error builder. Defaults to C<confess>.
877
878=item B<error_class $class_name>
879
880Get or set the error class. Has no default.
881
882=item B<create_error_confess %args>
883
884Creates an error using L<Carp/longmess>
885
886=item B<create_error_croak %args>
887
888Creates an error using L<Carp/shortmess>
889
890=item B<create_error_object %args>
891
892Calls C<new> on the C<class> parameter in C<%args>. Usable with C<error_class>
893to support custom error objects for your meta class.
894
895=item B<raise_error $error>
896
897Dies with an error object or string.
898
c0e30cf5 899=back
900
901=head1 BUGS
902
ac2dc464 903All complex software has bugs lurking in it, and this module is no
c0e30cf5 904exception. If you find a bug please either email me, or add the bug
905to cpan-RT.
906
c0e30cf5 907=head1 AUTHOR
908
909Stevan Little E<lt>stevan@iinteractive.comE<gt>
910
911=head1 COPYRIGHT AND LICENSE
912
778db3ac 913Copyright 2006-2008 by Infinity Interactive, Inc.
c0e30cf5 914
915L<http://www.iinteractive.com>
916
917This library is free software; you can redistribute it and/or modify
ac2dc464 918it under the same terms as Perl itself.
c0e30cf5 919
8a7a9c53 920=cut
1a563243 921