Hi,
This (aspect solution) is exactly what I was looking for !

Thanks everyone for the comments, it was fun and I learned a lot.

Ynon


On 10 February 2012 21:24, Jesse Luehrs <d...@tozt.net> wrote:

> On Fri, Feb 10, 2012 at 02:06:24PM -0500, Chris Prather wrote:
> > On Fri, Feb 10, 2012 at 12:27 PM, Ovid <curtis_ovid_...@yahoo.com>
> wrote:
> >
> >
> > > Of course, both Acme::Combat::Chipmunk and Acme::Combat::Normal
> implement the desired role. With that, you can swap out abilities as needed.
> >
> > What if Joe is bitten by a Chipmunk *and* a Zombie? You'll need to
> > carefully design your roles with composition in mind then. This is
> > what stopped my first go at this problem using an Array trait.
>
> Right, this is the key point here. Roles are designed for composition
> into classes, and have an interface that makes sense for that kind of
> use case (where you can handle method conflicts and such when you're
> actually writing the class). Runtime application to instances does work,
> but only really works well for very simple cases where there aren't very
> many things interacting. Once you start trying to model more complicated
> things with roles, you will end up writing just as much (if not more)
> code trying to force roles into the model that your system needs as you
> would if you had just written that explicitly from the start (and it
> will end up being more difficult to understand and maintain too).
>
> One alternative to having to hardcode specific aspect behavior into each
> action is to make the aspects classes rather than roles, and have those
> classes consume roles corresponding to the actions. For instance, you
> could do something along these lines (note that this is effectively the
> same sort of model as Dist::Zilla uses for plugins):
>
>  package Acme::Combat;
>  use Moose;
>
>  # ...
>
>  sub attack {
>      my $self = shift;
>      for my $aspect ($self->aspects_with('Attack')) {
>          $aspect->attack_effects(@_);
>      }
>  }
>
>  package Acme::Combat::Normal;
>  use Moose;
>
>  with 'Acme::Combat::Aspect::Attack';
>
>  sub attack_effects {
>      my $self = shift;
>      my ($opponent) = @_;
>      $opponent->decrease_hp(2);
>  }
>
> This way, you can just swap out which aspects are attached to a given
> class, and things will just work. The advantage here is that you're
> explicitly determining what the composition behavior should be, so you
> don't have to try to trick roles into doing what you want.
>
> -doy
>

Reply via email to