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


Antichamber_(PC)_15.png

Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations