Sometime the Roles we Play are Dead Ends
In my last post I used 'Moose::Util::TypeConstraints' to limit my ability scores to a range between 3~18 now onto the next little test for Moose.
The next rule I want to enforce is, if the passed in ability scores are a Grot Character, (one that can never have a class as all the scores are too low) then I want an error to be thrown.
I could of course just add in a bunch of 'if' or 'given' s in the 'BUILD' or 'around BUILDARGS' but that is not a very elegant solution and as 'Race' is chosen before 'Class' I may have to apply these rules more than once as a 'Demi-Human Character' abilities are adjusted which may preclude a 'Class' as well.
Like my earlier post I am going to give this a try with 'MooseX::Role::Parameterized' and see how far it gets me. What I am going to try is load in the 'Roles' for each 'Class' if at the end I get no class then I will error out.
As I like to reuse code I created a new type that I can apply to abilities as I added this into my 'RPG::ADD::Util::Types' package
subtype 'MinAbilityRoll_09',
as 'Int',
where { $_ > 8 },
message { "AbilityRoll must be above 8" };
So as a test I create a new role like this
package RPG::ADD::Character::Creator::Fighter;
use MooseX::Role::Parameterized;
use RPG::ADD::Util::Types;
parameter self => (
isa => 'RPG::ADD::Character::Creator',
required => 1,
);
parameter strength => (
isa => 'MinAbilityRoll_09',
required => 1,
);
role {
my $params = shift;
requires 'available_classes';
push(@{$params->{self}->available_classes()},__PACKAGE__);
};
which really just checks that strength is above '9' and if it passes then I add that class as one of my available_classes on the 'Creator' class.
In Creator I just add in the following
sub BUILD {
my $self = shift;
my ($attr) = @_;
$attr->{self} = $self;
unless(@{scalar($self->available_classes())}){
eval{
apply_all_roles($self,("RPG::ADD::Character::Creator::Fighter",=>$attr));
};
throw_exception( "NeitherRoleNorRoleNameIsGiven", {message=>"There can be no 'Class' for this set of ability roles?"})
unless(scalar(@{$self->available_classes()}));
}
}
Well it does work but is is what I want?? Looking at the above I know I will have to use something like Module::PluginFinder or alike to dynamically load in my 'Classes'. I just don't like the above very much as I think I am just 'Shifting Bobbins' here moving. i.e. moving my honking big 'if else' statement into roles and types and getting little back in return.
I know Makes the code a little cleaner and I can reuse little bits but not what I really want in the end. Hmm!!!
Perhaps I have it arse-backwards for this part of the application?? Well maybe next post I will try something else as this while not a dead end is ugly as spit
Leave a comment