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