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