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