Front page | perl.moose |
Postings from February 2012
Re: Removing a role
Thread Previous
From:
ynon perek
Date:
February 10, 2012 11:59
Subject:
Re: Removing a role
Message ID:
CAJ9Vtg_Nrdfswza6_jva5Jd_=pAZgSKp+sNNeZtKSK7XY7tWLA@mail.gmail.com
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 <doy@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_poe@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
>
Thread Previous