Out of the Barn Yard
As I am cozening up to Moose these days I wanted to play with Roles as one is suppose to be able to scurry around the Diamond problem with them, and having some background with Lisp and Smalltalk I knew of them.
Unfortunately like many many many other tutorial on OO we stayed firmly in the barnyard (well in moose's case a pet store) which of course is fine if you are an animal lover but I am always modeling something that is a much more complex as the idea of a 'Role' is much more abstracted and mulit-layed than differing animal noises as this little syllogism points out;
All dogs have a bark.
But not all things that have a bark are dogs.
So what would be a good example of something that is complex, mulit-layered, and demonstrates, to me at least, how roles should work?
Well I looked over on my book shelf and this caught my eye;
Why not? I though! So staring with page one we have "Character" and they all have names so lets start with that;
package Character;
use Moose;
has 'name' =>(
is =>'rw',
isa =>'Str', );
which leads me to my first thinking part.
We all know characters have 6 abilities and in the old days I would now simply give my class 6 attributes like this
has 'strength' =>(
is =>'rw',
isa =>'Int',
);
and then be on my merry way.
However, I want to explore what Moose can do for me. I have also been playing D&D long enough to know that these attributes are not fixed. They change with race, class, age and even magic. So I would have to add a bunch, such as, the initial value the present value, the non magic value etc. Hmm already looking like BBofM and I am only on line 5.
So lets see what Moose has to offer?
I could try one of these for each ability;
has 'strength' =>(
is =>'rw',
isa=>'Strength'
);
Where I have encapsulate each of my 'abilities' into its own class and just use them as attributes in my 'Character' class. I have done this many times in trad OO perl. Heck I could even create a base 'Ability' class and make each of my 'abilities' a child of that one.
Perhaps I could try this?
package Character;
use Moose;
with qw( Strength );
and bring 'Strength' in as a role?
Hmm let me sleep on that.
Well, an RPG character is a pretty complex entity; as I mentioned in my latest blog post, I've been trying to code it up for the past 30 years and have never been satisfied yet. :-)
But my standard advice for understanding roles applies here, I think: if your classes are your nouns and your methods are your verbs, your roles are your adjectives. So I think 'with Strength' feels a bit wonky.
I think what I might try to explore is to imagine a set of behaviours that could somehow encapsulate the handling of bonuses and penalties, many of which are conditional. I'd make that a role and call it 'Adjustable' or somesuch. Then have a class called 'Ability' that composed that role. Thus, your initial setup goes something like:
So 'strength' is just an instance of 'Ability', not a separate class. No clue how you'd actually implement Adjustable, but that seems like a workable structure to me.