X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FMeta%2FRole%2FApplication%2FRoleSummation.pm;h=e7db2a072d8a34cbfbd6225b7f7ccea03ce73df0;hb=0953b5a4784ae9e36130d87ad9bff255b5c581c8;hp=e30bccb09fb62763328a12a40bc62dfa1ed1255c;hpb=7e79d987b68fd31e41c5cafffa712710134b7f73;p=gitmo%2FMoose.git diff --git a/lib/Moose/Meta/Role/Application/RoleSummation.pm b/lib/Moose/Meta/Role/Application/RoleSummation.pm index e30bccb..e7db2a0 100644 --- a/lib/Moose/Meta/Role/Application/RoleSummation.pm +++ b/lib/Moose/Meta/Role/Application/RoleSummation.pm @@ -8,7 +8,7 @@ use Scalar::Util 'blessed'; use Moose::Meta::Role::Composite; -our $VERSION = '0.79'; +our $VERSION = '1.15'; $VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; @@ -22,11 +22,13 @@ __PACKAGE__->meta->add_attribute('role_params' => ( sub get_exclusions_for_role { my ($self, $role) = @_; $role = $role->name if blessed $role; - if ($self->role_params->{$role} && defined $self->role_params->{$role}->{excludes}) { - if (ref $self->role_params->{$role}->{excludes} eq 'ARRAY') { - return $self->role_params->{$role}->{excludes}; + my $excludes_key = exists $self->role_params->{$role}->{'-excludes'} ? + '-excludes' : 'excludes'; + if ($self->role_params->{$role} && defined $self->role_params->{$role}->{$excludes_key}) { + if (ref $self->role_params->{$role}->{$excludes_key} eq 'ARRAY') { + return $self->role_params->{$role}->{$excludes_key}; } - return [ $self->role_params->{$role}->{excludes} ]; + return [ $self->role_params->{$role}->{$excludes_key} ]; } return []; } @@ -34,8 +36,10 @@ sub get_exclusions_for_role { sub get_method_aliases_for_role { my ($self, $role) = @_; $role = $role->name if blessed $role; - if ($self->role_params->{$role} && defined $self->role_params->{$role}->{alias}) { - return $self->role_params->{$role}->{alias}; + my $alias_key = exists $self->role_params->{$role}->{'-alias'} ? + '-alias' : 'alias'; + if ($self->role_params->{$role} && defined $self->role_params->{$role}->{$alias_key}) { + return $self->role_params->{$role}->{$alias_key}; } return {}; } @@ -112,30 +116,36 @@ sub check_required_attributes { sub apply_attributes { my ($self, $c) = @_; - my @all_attributes = map { - my $role = $_; - map { - +{ - name => $_, - attr => $role->get_attribute($_), - } - } $role->get_attribute_list - } @{$c->get_roles}; + my @all_attributes; + + for my $role ( @{ $c->get_roles } ) { + push @all_attributes, + map { $role->get_attribute($_) } $role->get_attribute_list; + } my %seen; foreach my $attr (@all_attributes) { - if (exists $seen{$attr->{name}}) { - if ( $seen{$attr->{name}} != $attr->{attr} ) { - require Moose; - Moose->throw_error("We have encountered an attribute conflict with '" . $attr->{name} . "' " - . "during composition. This is fatal error and cannot be disambiguated.") - } + my $name = $attr->name; + + if ( exists $seen{$name} ) { + next if $seen{$name}->is_same_as($attr); + + my $role1 = $seen{$name}->associated_role->name; + my $role2 = $attr->associated_role->name; + + require Moose; + Moose->throw_error( + "We have encountered an attribute conflict with '$name' " + . "during role composition. " + . " This attribute is defined in both $role1 and $role2." + . " This is fatal error and cannot be disambiguated." ); } - $seen{$attr->{name}} = $attr->{attr}; + + $seen{$name} = $attr; } foreach my $attr (@all_attributes) { - $c->add_attribute($attr->{name}, $attr->{attr}); + $c->add_attribute( $attr->clone ); } } @@ -154,7 +164,9 @@ sub apply_methods { name => $_, method => $role->get_method($_), } - } $role->get_method_list), + } map { $_->name } + grep { !$_->isa('Class::MOP::Method::Meta') } + $role->_get_local_methods), (map { +{ role => $role, @@ -167,15 +179,21 @@ sub apply_methods { my (%seen, %method_map); foreach my $method (@all_methods) { - if (exists $seen{$method->{name}}) { - if ($seen{$method->{name}}->body != $method->{method}->body) { - $c->add_required_methods($method->{name}); + my $seen = $seen{$method->{name}}; + + if ($seen) { + if ($seen->{method}->body != $method->{method}->body) { + $c->add_conflicting_method( + name => $method->{name}, + roles => [$method->{role}->name, $seen->{role}->name], + ); + delete $method_map{$method->{name}}; next; } } - $seen{$method->{name}} = $method->{method}; + $seen{$method->{name}} = $method; $method_map{$method->{name}} = $method->{method}; } @@ -289,9 +307,7 @@ bindings and 'disabling' the conflicting bindings =head1 BUGS -All complex software has bugs lurking in it, and this module is no -exception. If you find a bug please either email me, or add the bug -to cpan-RT. +See L for details on reporting bugs. =head1 AUTHOR @@ -299,7 +315,7 @@ Stevan Little Estevan@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2006-2009 by Infinity Interactive, Inc. +Copyright 2006-2010 by Infinity Interactive, Inc. L