Looking for Moose in all the Wrong Places

In my last post I again ending up like poor Keith Haring in his picture below.

13-Ptgintocorner04.jpg

I programmed what I wanted but it was beginning to look like the same stuff I started with.

So playing around a bit I remembered that Moose has the before, after and around Method Modifiers that work like DBI's callbacks that some of you might remember form one of my earlier posts. The great thing about these is that can be used from inside a role for code outside the role as long as the code is referenced in a 'requires'.

So I to move the max values out of the Character class and into the Dwarf role I gave this a shot


 requires 'charisma';
 before 'charisma' => sub { my $self = shift;
                                     $self->charisma(16)
                                        if $self->charisma() >16;};

It only took one quick run of my code to see the silly mistake I made. Seems calling ones self and then setting ones self before calling ones self is not a good idea. Can you spell?

I have played with Mojo and Dancer enough to realize what I have done. So I will have to give up that Idea.

However, these little gems do look like they will be very handy when it comes time to do other things in my character class.

I could see the 'around' could be use this in my 'Saving throw bonus against Magic wands, staves, rods and spells ' role something like this;


package BonusAgainstWSRS;
use 5.010;
use Moose::Role;
requires 'constitution';

around 'save_vs_WSR' => sub {
my $original = shift;
my $self = shift;
my ($bonus) = @_;
return $self->$original($bonus+$self->_WSRS_bonus());

};

around 'save_vs_spell' => sub {
my $original = shift;
my $self = shift;
my ($bonus) = @_;
return $self->$original($bonus+$self->_WSRS_bonus());

};

sub _WSRS_bonus {
my $self = shift;
given ($self->constitution()){
when ([0..3]){
return 0;
};
when ([4..6]){
return 1;
};
when ([7..10]){
return 2;
};
when ([11..13]){
return 3;
};
when ([14..17]){
return 4;
};
default{
return 4;
};
};
}

Back to my intimidate problem of the Max values, I think after all I do not really have to worry about them at the instance level because in game play the Max values are reduced at character creation time and the original scores should be kept as well (hopefully).

Now my only other annoying little problem is the long 'if' or 'given' in my BEGIN sub to set the race role.


use Dwarf;
use Elf;
...
sub BUILD {
      my $self = shift;
      my ($attr) = @_;
      
 if ($self->race() eq 'Dwarf'){
		Dwarf->meta->apply($self);
  elsif ...

Sure enough in Moose there is a way around that and that is using one of the handy Moose::Util functions.

I just do is this;


package Character;
use Moose;
use Moose::Util  qw(apply_all_roles);
sub BUILD {
      my $self = shift;
      my ($attr) = @_;
      apply_all_roles($self, $self->race());
  };

and my 'race' what ever it might be will be applied. I even get rid of that nasty 'use Dwarf'. Very neat, much cleaner than my original and as a plus the 'apply_all_roles' takes an array so thinking ahead I could also add my characters Player Class/es here as well.

Moose really does give you that little bit extra.

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