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