Made the delegation closure have useful error trace information.
[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 );
349cda54 11use List::MoreUtils qw( any all uniq first_index );
21f1e231 12use Scalar::Util 'weaken', 'blessed';
a15dff8d 13
870d0f1a 14our $VERSION = '0.94';
e606ae5f 15$VERSION = eval $VERSION;
d44714be 16our $AUTHORITY = 'cpan:STEVAN';
bc1e29b5 17
74862722 18use Moose::Meta::Method::Overridden;
3f9e4b0a 19use Moose::Meta::Method::Augmented;
77f14411 20use Moose::Error::Default;
0fa70d03 21use Moose::Meta::Class::Immutable::Trait;
22use Moose::Meta::Method::Constructor;
23use Moose::Meta::Method::Destructor;
8ee73eeb 24
c0e30cf5 25use base 'Class::MOP::Class';
26
598340d5 27__PACKAGE__->meta->add_attribute('roles' => (
ef333f17 28 reader => 'roles',
29 default => sub { [] }
30));
31
a9b63d79 32__PACKAGE__->meta->add_attribute('role_applications' => (
639f9a1a 33 reader => '_get_role_applications',
a9b63d79 34 default => sub { [] }
35));
36
0fa70d03 37__PACKAGE__->meta->add_attribute(
38 Class::MOP::Attribute->new('immutable_trait' => (
39 accessor => "immutable_trait",
40 default => 'Moose::Meta::Class::Immutable::Trait',
41 ))
42);
43
e606ae5f 44__PACKAGE__->meta->add_attribute('constructor_class' => (
45 accessor => 'constructor_class',
e0001338 46 default => 'Moose::Meta::Method::Constructor',
e606ae5f 47));
48
49__PACKAGE__->meta->add_attribute('destructor_class' => (
50 accessor => 'destructor_class',
e0001338 51 default => 'Moose::Meta::Method::Destructor',
e606ae5f 52));
53
11c86f15 54__PACKAGE__->meta->add_attribute('error_class' => (
bf6fa6b3 55 accessor => 'error_class',
56 default => 'Moose::Error::Default',
11c86f15 57));
58
590868a3 59sub initialize {
60 my $class = shift;
61 my $pkg = shift;
d03bd989 62 return Class::MOP::get_metaclass_by_name($pkg)
685f7e44 63 || $class->SUPER::initialize($pkg,
64 'attribute_metaclass' => 'Moose::Meta::Attribute',
65 'method_metaclass' => 'Moose::Meta::Method',
66 'instance_metaclass' => 'Moose::Meta::Instance',
67 @_
d03bd989 68 );
ac2dc464 69}
590868a3 70
f785aad8 71sub reinitialize {
72 my $self = shift;
73 my $pkg = shift;
74
75 my $meta = blessed $pkg ? $pkg : Class::MOP::class_of($pkg);
76
77 my %existing_classes;
78 if ($meta) {
79 %existing_classes = map { $_ => $meta->$_() } qw(
80 attribute_metaclass
81 method_metaclass
82 wrapped_method_metaclass
83 instance_metaclass
84 constructor_class
85 destructor_class
86 error_class
87 );
88 }
89
90 return $self->SUPER::reinitialize(
91 $pkg,
92 %existing_classes,
93 @_,
94 );
95}
96
0fa70d03 97sub _immutable_options {
98 my ( $self, @args ) = @_;
99
100 $self->SUPER::_immutable_options(
101 inline_destructor => 1,
102
103 # Moose always does this when an attribute is created
104 inline_accessors => 0,
8aeb5bfd 105 inline_delegations => 1,
0fa70d03 106
107 @args,
108 );
109}
110
8aeb5bfd 111sub _install_inlined_code {
112 my ( $self, %args ) = @_;
113
114 $self->SUPER::_install_inlined_code(%args);
115 $self->_inline_delegations(%args) if $args{inline_delegations};
116}
117
118sub _inline_delegations {
119 my $self = shift;
120 foreach my $attr_name ( $self->get_attribute_list ) {
121 my $attr = $self->get_attribute($attr_name);
122 $attr->install_delegation(1) if $attr->can('install_delegation');
123 }
124}
125
61bdd94f 126sub create {
127 my ($self, $package_name, %options) = @_;
d03bd989 128
61bdd94f 129 (ref $options{roles} eq 'ARRAY')
11c86f15 130 || $self->throw_error("You must pass an ARRAY ref of roles", data => $options{roles})
61bdd94f 131 if exists $options{roles};
310ba883 132 my $roles = delete $options{roles};
dd37a5be 133
61bdd94f 134 my $class = $self->SUPER::create($package_name, %options);
dd37a5be 135
310ba883 136 if ($roles) {
137 Moose::Util::apply_all_roles( $class, @$roles );
61bdd94f 138 }
d03bd989 139
61bdd94f 140 return $class;
141}
142
6a4a7c31 143sub _check_metaclass_compatibility {
2b72f3b4 144 my $self = shift;
145
146 if ( my @supers = $self->superclasses ) {
147 $self->_fix_metaclass_incompatibility(@supers);
148 }
149
6a4a7c31 150 $self->SUPER::_check_metaclass_compatibility(@_);
2b72f3b4 151}
152
17594769 153my %ANON_CLASSES;
154
155sub create_anon_class {
156 my ($self, %options) = @_;
157
158 my $cache_ok = delete $options{cache};
d03bd989 159
17594769 160 # something like Super::Class|Super::Class::2=Role|Role::1
161 my $cache_key = join '=' => (
11aaed6c 162 join('|', @{$options{superclasses} || []}),
163 join('|', sort @{$options{roles} || []}),
17594769 164 );
d03bd989 165
6d5cbd2b 166 if ($cache_ok && defined $ANON_CLASSES{$cache_key}) {
17594769 167 return $ANON_CLASSES{$cache_key};
168 }
d03bd989 169
17594769 170 my $new_class = $self->SUPER::create_anon_class(%options);
171
6d5cbd2b 172 $ANON_CLASSES{$cache_key} = $new_class
173 if $cache_ok;
17594769 174
175 return $new_class;
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
ef333f17 204sub does_role {
205 my ($self, $role_name) = @_;
322abb07 206
ef333f17 207 (defined $role_name)
11c86f15 208 || $self->throw_error("You must supply a role name to look for");
322abb07 209
9c429218 210 foreach my $class ($self->class_precedence_list) {
322abb07 211 my $meta = Class::MOP::class_of($class);
3d0f5a27 212 # when a Moose metaclass is itself extended with a role,
213 # this check needs to be done since some items in the
214 # class_precedence_list might in fact be Class::MOP
215 # based still.
322abb07 216 next unless $meta && $meta->can('roles');
217 foreach my $role (@{$meta->roles}) {
9c429218 218 return 1 if $role->does_role($role_name);
219 }
ef333f17 220 }
221 return 0;
222}
223
d79e62fd 224sub excludes_role {
225 my ($self, $role_name) = @_;
ebfc4d0f 226
d79e62fd 227 (defined $role_name)
11c86f15 228 || $self->throw_error("You must supply a role name to look for");
ebfc4d0f 229
ac2dc464 230 foreach my $class ($self->class_precedence_list) {
ebfc4d0f 231 my $meta = Class::MOP::class_of($class);
232 # when a Moose metaclass is itself extended with a role,
233 # this check needs to be done since some items in the
234 # class_precedence_list might in fact be Class::MOP
235 # based still.
236 next unless $meta && $meta->can('roles');
237 foreach my $role (@{$meta->roles}) {
9c429218 238 return 1 if $role->excludes_role($role_name);
239 }
d79e62fd 240 }
241 return 0;
242}
243
8c9d74e7 244sub new_object {
1308deb4 245 my $class = shift;
e606ae5f 246 my $params = @_ == 1 ? $_[0] : {@_};
1308deb4 247 my $self = $class->SUPER::new_object($params);
248
b2df9268 249 foreach my $attr ( $class->get_all_attributes() ) {
1308deb4 250
251 next unless $attr->can('has_trigger') && $attr->has_trigger;
252
253 my $init_arg = $attr->init_arg;
254
255 next unless defined $init_arg;
256
257 next unless exists $params->{$init_arg};
258
259 $attr->trigger->(
260 $self,
261 (
262 $attr->should_coerce
263 ? $attr->get_read_method_ref->($self)
264 : $params->{$init_arg}
265 ),
1308deb4 266 );
8c9d74e7 267 }
1308deb4 268
ac2dc464 269 return $self;
8c9d74e7 270}
271
e2eef3a5 272sub superclasses {
273 my $self = shift;
274 my @supers = @_;
275 foreach my $super (@supers) {
c8d9f1e2 276 Class::MOP::load_class($super);
277 my $meta = Class::MOP::class_of($super);
9f0bc5ec 278 $self->throw_error("You cannot inherit from a Moose Role ($super)")
e2eef3a5 279 if $meta && $meta->isa('Moose::Meta::Role')
280 }
281 return $self->SUPER::superclasses(@supers);
282}
283
093b12c2 284### ---------------------------------------------
285
a2eec5e7 286sub add_attribute {
287 my $self = shift;
28af3424 288 my $attr =
e472c9a5 289 (blessed $_[0] && $_[0]->isa('Class::MOP::Attribute')
d03bd989 290 ? $_[0]
28af3424 291 : $self->_process_attribute(@_));
292 $self->SUPER::add_attribute($attr);
293 # it may be a Class::MOP::Attribute, theoretically, which doesn't have
294 # 'bare' and doesn't implement this method
9340e346 295 if ($attr->can('_check_associated_methods')) {
296 $attr->_check_associated_methods;
28af3424 297 }
298 return $attr;
a2eec5e7 299}
300
78cd1d3b 301sub add_override_method_modifier {
302 my ($self, $name, $method, $_super_package) = @_;
18c2ec0e 303
d05cd563 304 (!$self->has_method($name))
11c86f15 305 || $self->throw_error("Cannot add an override method if a local method is already present");
18c2ec0e 306
74862722 307 $self->add_method($name => Moose::Meta::Method::Overridden->new(
3f9e4b0a 308 method => $method,
309 class => $self,
310 package => $_super_package, # need this for roles
311 name => $name,
18c2ec0e 312 ));
78cd1d3b 313}
314
315sub add_augment_method_modifier {
ac2dc464 316 my ($self, $name, $method) = @_;
d05cd563 317 (!$self->has_method($name))
11c86f15 318 || $self->throw_error("Cannot add an augment method if a local method is already present");
3f9e4b0a 319
320 $self->add_method($name => Moose::Meta::Method::Augmented->new(
321 method => $method,
322 class => $self,
323 name => $name,
324 ));
78cd1d3b 325}
326
1341f10c 327## Private Utility methods ...
328
05d9eaf6 329sub _find_next_method_by_name_which_is_not_overridden {
330 my ($self, $name) = @_;
68efb014 331 foreach my $method ($self->find_all_methods_by_name($name)) {
ac2dc464 332 return $method->{code}
74862722 333 if blessed($method->{code}) && !$method->{code}->isa('Moose::Meta::Method::Overridden');
05d9eaf6 334 }
335 return undef;
336}
337
41419b9e 338sub _fix_metaclass_incompatibility {
1341f10c 339 my ($self, @superclasses) = @_;
e606ae5f 340
57a21623 341 $self->_fix_one_incompatible_metaclass($_)
342 for map { Moose::Meta::Class->initialize($_) } @superclasses;
349cda54 343}
344
345sub _fix_one_incompatible_metaclass {
346 my ($self, $meta) = @_;
e606ae5f 347
349cda54 348 return if $self->_superclass_meta_is_compatible($meta);
349
350 unless ( $self->is_pristine ) {
351 $self->throw_error(
352 "Cannot attempt to reinitialize metaclass for "
353 . $self->name
354 . ", it isn't pristine" );
f8b6827f 355 }
cb311121 356
349cda54 357 $self->_reconcile_with_superclass_meta($meta);
f8b6827f 358}
359
360sub _superclass_meta_is_compatible {
349cda54 361 my ($self, $super_meta) = @_;
f8b6827f 362
363 next unless $super_meta->isa("Class::MOP::Class");
364
365 my $super_meta_name
366 = $super_meta->is_immutable
989263ad 367 ? $super_meta->_get_mutable_metaclass_name
f8b6827f 368 : ref($super_meta);
369
370 return 1
371 if $self->isa($super_meta_name)
372 and
373 $self->instance_metaclass->isa( $super_meta->instance_metaclass );
374}
375
376# I don't want to have to type this >1 time
377my @MetaClassTypes =
3e334262 378 qw( attribute_metaclass
379 method_metaclass
380 wrapped_method_metaclass
381 instance_metaclass
382 constructor_class
383 destructor_class
384 error_class );
f8b6827f 385
386sub _reconcile_with_superclass_meta {
349cda54 387 my ($self, $super_meta) = @_;
f8b6827f 388
dd37a5be 389 my $super_meta_name
f8b6827f 390 = $super_meta->is_immutable
989263ad 391 ? $super_meta->_get_mutable_metaclass_name
f8b6827f 392 : ref($super_meta);
e606ae5f 393
f8b6827f 394 my $self_metaclass = ref $self;
395
396 # If neither of these is true we have a more serious
397 # incompatibility that we just cannot fix (yet?).
dd37a5be 398 if ( $super_meta_name->isa( ref $self )
f8b6827f 399 && all { $super_meta->$_->isa( $self->$_ ) } @MetaClassTypes ) {
0635500e 400 $self->_reinitialize_with($super_meta);
f8b6827f 401 }
402 elsif ( $self->_all_metaclasses_differ_by_roles_only($super_meta) ) {
0635500e 403 $self->_reconcile_role_differences($super_meta);
1341f10c 404 }
1341f10c 405}
406
f8b6827f 407sub _reinitialize_with {
408 my ( $self, $new_meta ) = @_;
409
0635500e 410 my $new_self = $new_meta->reinitialize(
f8b6827f 411 $self->name,
412 attribute_metaclass => $new_meta->attribute_metaclass,
413 method_metaclass => $new_meta->method_metaclass,
414 instance_metaclass => $new_meta->instance_metaclass,
415 );
416
8b1d510f 417 $new_self->$_( $new_meta->$_ )
418 for qw( constructor_class destructor_class error_class );
f8b6827f 419
0635500e 420 %$self = %$new_self;
421
422 bless $self, ref $new_self;
423
4c5fcc12 424 # We need to replace the cached metaclass instance or else when it
425 # goes out of scope Class::MOP::Class destroy's the namespace for
426 # the metaclass's class, causing much havoc.
0635500e 427 Class::MOP::store_metaclass_by_name( $self->name, $self );
4c5fcc12 428 Class::MOP::weaken_metaclass( $self->name ) if $self->is_anon_class;
f8b6827f 429}
430
431# In the more complex case, we share a common ancestor with our
432# superclass's metaclass, but each metaclass (ours and the parent's)
433# has a different set of roles applied. We reconcile this by first
434# reinitializing into the parent class, and _then_ applying our own
435# roles.
436sub _all_metaclasses_differ_by_roles_only {
437 my ($self, $super_meta) = @_;
438
439 for my $pair (
440 [ ref $self, ref $super_meta ],
441 map { [ $self->$_, $super_meta->$_ ] } @MetaClassTypes
442 ) {
443
444 next if $pair->[0] eq $pair->[1];
445
446 my $self_meta_meta = Class::MOP::Class->initialize( $pair->[0] );
447 my $super_meta_meta = Class::MOP::Class->initialize( $pair->[1] );
448
449 my $common_ancestor
450 = _find_common_ancestor( $self_meta_meta, $super_meta_meta );
451
452 return unless $common_ancestor;
453
454 return
455 unless _is_role_only_subclass_of(
456 $self_meta_meta,
457 $common_ancestor,
458 )
459 && _is_role_only_subclass_of(
460 $super_meta_meta,
461 $common_ancestor,
462 );
463 }
464
465 return 1;
466}
467
468# This, and some other functions, could be called as methods, but
469# they're not for two reasons. One, we just end up ignoring the first
470# argument, because we can't call these directly on one of the real
471# arguments, because one of them could be a Class::MOP::Class object
472# and not a Moose::Meta::Class. Second, only a completely insane
473# person would attempt to subclass this stuff!
474sub _find_common_ancestor {
475 my ($meta1, $meta2) = @_;
476
477 # FIXME? This doesn't account for multiple inheritance (not sure
478 # if it needs to though). For example, is somewhere in $meta1's
db9fda52 479 # history it inherits from both ClassA and ClassB, and $meta2
f8b6827f 480 # inherits from ClassB & ClassA, does it matter? And what crazy
481 # fool would do that anyway?
482
483 my %meta1_parents = map { $_ => 1 } $meta1->linearized_isa;
484
485 return first { $meta1_parents{$_} } $meta2->linearized_isa;
486}
487
488sub _is_role_only_subclass_of {
489 my ($meta, $ancestor) = @_;
490
491 return 1 if $meta->name eq $ancestor;
492
493 my @roles = _all_roles_until( $meta, $ancestor );
494
495 my %role_packages = map { $_->name => 1 } @roles;
496
497 my $ancestor_meta = Class::MOP::Class->initialize($ancestor);
498
499 my %shared_ancestors = map { $_ => 1 } $ancestor_meta->linearized_isa;
500
501 for my $method ( $meta->get_all_methods() ) {
502 next if $method->name eq 'meta';
503 next if $method->can('associated_attribute');
504
505 next
506 if $role_packages{ $method->original_package_name }
507 || $shared_ancestors{ $method->original_package_name };
508
509 return 0;
510 }
511
512 # FIXME - this really isn't right. Just because an attribute is
513 # defined in a role doesn't mean it isn't _also_ defined in the
514 # subclass.
515 for my $attr ( $meta->get_all_attributes ) {
516 next if $shared_ancestors{ $attr->associated_class->name };
517
518 next if any { $_->has_attribute( $attr->name ) } @roles;
519
520 return 0;
521 }
522
523 return 1;
524}
525
526sub _all_roles {
527 my $meta = shift;
528
529 return _all_roles_until($meta);
530}
531
532sub _all_roles_until {
533 my ($meta, $stop_at_class) = @_;
534
535 return unless $meta->can('calculate_all_roles');
536
537 my @roles = $meta->calculate_all_roles;
538
539 for my $class ( $meta->linearized_isa ) {
540 last if $stop_at_class && $stop_at_class eq $class;
541
542 my $meta = Class::MOP::Class->initialize($class);
543 last unless $meta->can('calculate_all_roles');
544
545 push @roles, $meta->calculate_all_roles;
546 }
547
8b1d510f 548 return uniq @roles;
f8b6827f 549}
550
551sub _reconcile_role_differences {
552 my ($self, $super_meta) = @_;
553
3897e146 554 my $self_meta = Class::MOP::class_of($self);
f8b6827f 555
556 my %roles;
557
558 if ( my @roles = map { $_->name } _all_roles($self_meta) ) {
559 $roles{metaclass_roles} = \@roles;
560 }
561
562 for my $thing (@MetaClassTypes) {
563 my $name = $self->$thing();
564
565 my $thing_meta = Class::MOP::Class->initialize($name);
566
567 my @roles = map { $_->name } _all_roles($thing_meta)
568 or next;
569
570 $roles{ $thing . '_roles' } = \@roles;
571 }
572
2b72f3b4 573 $self->_reinitialize_with($super_meta);
f8b6827f 574
575 Moose::Util::MetaRole::apply_metaclass_roles(
576 for_class => $self->name,
577 %roles,
578 );
579
580 return $self;
581}
582
1341f10c 583sub _process_attribute {
a3738e5b 584 my ( $self, $name, @args ) = @_;
7e59b803 585
586 @args = %{$args[0]} if scalar @args == 1 && ref($args[0]) eq 'HASH';
d9bb6c63 587
f9b5f5f8 588 if (($name || '') =~ /^\+(.*)/) {
7e59b803 589 return $self->_process_inherited_attribute($1, @args);
1341f10c 590 }
591 else {
7e59b803 592 return $self->_process_new_attribute($name, @args);
593 }
594}
595
596sub _process_new_attribute {
597 my ( $self, $name, @args ) = @_;
7e59b803 598
d5c30e52 599 $self->attribute_metaclass->interpolate_class_and_new($name, @args);
1341f10c 600}
601
602sub _process_inherited_attribute {
603 my ($self, $attr_name, %options) = @_;
604 my $inherited_attr = $self->find_attribute_by_name($attr_name);
605 (defined $inherited_attr)
329c5dd4 606 || $self->throw_error("Could not find an attribute by the name of '$attr_name' to inherit from in ${\$self->name}", data => $attr_name);
1341f10c 607 if ($inherited_attr->isa('Moose::Meta::Attribute')) {
d7d8a8c7 608 return $inherited_attr->clone_and_inherit_options(%options);
1341f10c 609 }
610 else {
611 # NOTE:
612 # kind of a kludge to handle Class::MOP::Attributes
d7d8a8c7 613 return $inherited_attr->Moose::Meta::Attribute::clone_and_inherit_options(%options);
ac2dc464 614 }
1341f10c 615}
616
5cf3dbcf 617## -------------------------------------------------
618
bf6fa6b3 619our $error_level;
11c86f15 620
621sub throw_error {
622 my ( $self, @args ) = @_;
bf6fa6b3 623 local $error_level = ($error_level || 0) + 1;
11c86f15 624 $self->raise_error($self->create_error(@args));
625}
626
627sub raise_error {
628 my ( $self, @args ) = @_;
629 die @args;
630}
631
632sub create_error {
633 my ( $self, @args ) = @_;
634
18748ad6 635 require Carp::Heavy;
636
bf6fa6b3 637 local $error_level = ($error_level || 0 ) + 1;
18748ad6 638
11c86f15 639 if ( @args % 2 == 1 ) {
640 unshift @args, "message";
641 }
642
fcab1742 643 my %args = ( metaclass => $self, last_error => $@, @args );
11c86f15 644
bf6fa6b3 645 $args{depth} += $error_level;
11c86f15 646
bf6fa6b3 647 my $class = ref $self ? $self->error_class : "Moose::Error::Default";
11c86f15 648
a810a01f 649 Class::MOP::load_class($class);
650
11c86f15 651 $class->new(
bf6fa6b3 652 Carp::caller_info($args{depth}),
653 %args
11c86f15 654 );
655}
656
c0e30cf5 6571;
658
659__END__
660
661=pod
662
663=head1 NAME
664
e522431d 665Moose::Meta::Class - The Moose metaclass
c0e30cf5 666
c0e30cf5 667=head1 DESCRIPTION
668
70bb0f97 669This class is a subclass of L<Class::MOP::Class> that provides
670additional Moose-specific functionality.
e522431d 671
7854b409 672To really understand this class, you will need to start with the
673L<Class::MOP::Class> documentation. This class can be understood as a
674set of additional features on top of the basic feature provided by
675that parent class.
6ba6d68c 676
d4b1449e 677=head1 INHERITANCE
678
679C<Moose::Meta::Class> is a subclass of L<Class::MOP::Class>.
680
c0e30cf5 681=head1 METHODS
682
683=over 4
684
70bb0f97 685=item B<< Moose::Meta::Class->initialize($package_name, %options) >>
590868a3 686
70bb0f97 687This overrides the parent's method in order to provide its own
688defaults for the C<attribute_metaclass>, C<instance_metaclass>, and
689C<method_metaclass> options.
61bdd94f 690
70bb0f97 691These all default to the appropriate Moose class.
61bdd94f 692
70bb0f97 693=item B<< Moose::Meta::Class->create($package_name, %options) >>
17594769 694
70bb0f97 695This overrides the parent's method in order to accept a C<roles>
9e25a72a 696option. This should be an array reference containing roles
697that the class does, each optionally followed by a hashref of options
698(C<-excludes> and C<-alias>).
17594769 699
70bb0f97 700 my $metaclass = Moose::Meta::Class->create( 'New::Class', roles => [...] );
17594769 701
70bb0f97 702=item B<< Moose::Meta::Class->create_anon_class >>
17594769 703
70bb0f97 704This overrides the parent's method to accept a C<roles> option, just
705as C<create> does.
5cf3dbcf 706
70bb0f97 707It also accepts a C<cache> option. If this is true, then the anonymous
708class will be cached based on its superclasses and roles. If an
709existing anonymous class in the cache has the same superclasses and
710roles, it will be reused.
ac2dc464 711
70bb0f97 712 my $metaclass = Moose::Meta::Class->create_anon_class(
713 superclasses => ['Foo'],
714 roles => [qw/Some Roles Go Here/],
715 cache => 1,
716 );
ac2dc464 717
70bb0f97 718=item B<< $metaclass->make_immutable(%options) >>
ac2dc464 719
70bb0f97 720This overrides the parent's method to add a few options. Specifically,
721it uses the Moose-specific constructor and destructor classes, and
722enables inlining the destructor.
8c9d74e7 723
70bb0f97 724Also, since Moose always inlines attributes, it sets the
725C<inline_accessors> option to false.
02a0fb52 726
70bb0f97 727=item B<< $metaclass->new_object(%params) >>
a15dff8d 728
70bb0f97 729This overrides the parent's method in order to add support for
730attribute triggers.
6ba6d68c 731
70bb0f97 732=item B<< $metaclass->add_override_method_modifier($name, $sub) >>
ef1d5f4b 733
70bb0f97 734This adds an C<override> method modifier to the package.
e9ec68d6 735
70bb0f97 736=item B<< $metaclass->add_augment_method_modifier($name, $sub) >>
e9ec68d6 737
70bb0f97 738This adds an C<augment> method modifier to the package.
78cd1d3b 739
70bb0f97 740=item B<< $metaclass->calculate_all_roles >>
02a0fb52 741
70bb0f97 742This will return a unique array of C<Moose::Meta::Role> instances
743which are attached to this class.
78cd1d3b 744
70bb0f97 745=item B<< $metaclass->add_role($role) >>
02a0fb52 746
70bb0f97 747This takes a L<Moose::Meta::Role> object, and adds it to the class's
748list of roles. This I<does not> actually apply the role to the class.
2b14ac61 749
b90dd4ef 750=item B<< $metaclass->role_applications >>
751
639f9a1a 752Returns a list of L<Moose::Meta::Role::Application::ToClass>
b90dd4ef 753objects, which contain the arguments to role application.
754
755=item B<< $metaclass->add_role_application($application) >>
756
757This takes a L<Moose::Meta::Role::Application::ToClass> object, and
758adds it to the class's list of role applications. This I<does not>
759actually apply any role to the class; it is only for tracking role
760applications.
761
560c498d 762=item B<< $metaclass->does_role($role) >>
ef333f17 763
560c498d 764This returns a boolean indicating whether or not the class does the specified
765role. The role provided can be either a role name or a L<Moose::Meta::Role>
766object. This tests both the class and its parents.
02a0fb52 767
70bb0f97 768=item B<< $metaclass->excludes_role($role_name) >>
ef333f17 769
70bb0f97 770A class excludes a role if it has already composed a role which
771excludes the named role. This tests both the class and its parents.
02a0fb52 772
70bb0f97 773=item B<< $metaclass->add_attribute($attr_name, %params|$params) >>
ef333f17 774
70bb0f97 775This overrides the parent's method in order to allow the parameters to
776be provided as a hash reference.
02a0fb52 777
70bb0f97 778=item B<< $metaclass->constructor_class ($class_name) >>
d79e62fd 779
70bb0f97 780=item B<< $metaclass->destructor_class ($class_name) >>
e606ae5f 781
782These are the names of classes used when making a class
783immutable. These default to L<Moose::Meta::Method::Constructor> and
784L<Moose::Meta::Method::Destructor> respectively. These accessors are
785read-write, so you can use them to change the class name.
786
70bb0f97 787=item B<< $metaclass->error_class($class_name) >>
8b1d510f 788
70bb0f97 789The name of the class used to throw errors. This defaults to
8b1d510f 790L<Moose::Error::Default>, which generates an error with a stacktrace
791just like C<Carp::confess>.
792
70bb0f97 793=item B<< $metaclass->throw_error($message, %extra) >>
11c86f15 794
795Throws the error created by C<create_error> using C<raise_error>
796
c0e30cf5 797=back
798
799=head1 BUGS
800
d4048ef3 801See L<Moose/BUGS> for details on reporting bugs.
c0e30cf5 802
c0e30cf5 803=head1 AUTHOR
804
805Stevan Little E<lt>stevan@iinteractive.comE<gt>
806
807=head1 COPYRIGHT AND LICENSE
808
7e0492d3 809Copyright 2006-2010 by Infinity Interactive, Inc.
c0e30cf5 810
811L<http://www.iinteractive.com>
812
813This library is free software; you can redistribute it and/or modify
ac2dc464 814it under the same terms as Perl itself.
c0e30cf5 815
8a7a9c53 816=cut
1a563243 817