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