Hi, I liked better the fact that roles could change behavior in the consumer class - thus provide a much cleaner interface (less coupling). In the abilities suggestion, attach subroutine must take into account in its code all the possible abilities.
Consider the following roles: package Abilities::Strong; use Moose::Role; with 'Abilities::Base'; after attack => sub { my ($self, $enemy) = @_; $enemy->lose_life(2); }; package Abilities::Undead; use Moose::Role; use Moose::Util qw/apply_all_roles/; with 'Abilities::Base'; after 'attack' => sub { my ($self, $enemy) = @_; apply_all_roles($enemy, 'Abilities::Undead'); }; That scheme allows more flexibility in coding new abilities as plugins later on. (working code at: https://gist.github.com/1791637) On 10 February 2012 18:52, Nick Perez <n...@nickandperla.net> wrote: > On Fri, 10 Feb 2012 18:07:58 +0200 > ynon perek <ynonpe...@gmail.com> wrote: > > > Is it also possible to remove a role from an instance ? > > While it would seemingly make sense to (ab)use the roles/traits system > for something like this, it probably is a better idea to have an > attribute that contains a list of abilities that the instance could use > to determine its actions. > > has abilities => ( > is => 'ro', > traits => [qw/Hash/], > isa => 'HashRef', > default => sub { +{} }, > handles => { > has_ability => 'exists', > get_ability => 'get', > set_ability => 'set', > } > ); > > ... > > sub deal_damage { > my ($self) = @_; > return $self->base_damage + ($self->has_ability('Strong') ? > $self->get_ability : 0); > } > > # attack > $badguy->set_ability('Strong' => 5); > > $target->receive_damage($badguy->deal_damage); > > > Doing it this way also makes it easier to serialize (like making save > file). > > > -- > > Nicholas Perez > XMPP/Email: n...@nickandperla.net > http://search.cpan.org/~nperez/ > http://github.com/nperez >