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
>

Reply via email to