Why a trait here? Define an interface (a role with only 'requires') and 
delegate off to objects which do that interface.

has abilities => (
  is => 'rw',
  does => 'Acme::Role::Combat',
  default => sub { Acme::Combat::Normal->new },
  handles => [qw/
    attack
    defend
    run
    hide
  /],
);


And later:

  my $character = Acme::Character->new({
    name => "Joe Blow",
    %other_characteristics,
  })

And later, when Joe Blow gets bitten by the radioactive chipmunk:

  $character->abilities(Acme::Combat::Chipmunk->new);

And when it wears off:

  $character->abilities(Acme::Combat::Normal->new);

Of course, both Acme::Combat::Chipmunk and Acme::Combat::Normal implement the 
desired role. With that, you can swap out abilities as needed.

Or am I misunderstanding something?

Cheers,
Ovid
--
Live and work overseas - http://overseas-exile.blogspot.com/
Buy the book           - http://www.oreilly.com/catalog/perlhks/
Tech blog              - http://blogs.perl.org/users/ovid/
Twitter                - http://twitter.com/OvidPerl/


>________________________________
> From: Nick Perez <n...@nickandperla.net>
>To: ynon perek <ynonpe...@gmail.com> 
>Cc: moose@perl.org 
>Sent: Friday, 10 February 2012, 17:52
>Subject: Re: Removing a role
> 
>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