Building A Better Moose Trap

Seem there are a number of little oddities in Moose that take a little time to absorb, but once you figure them out you wonder what you ever did before. In my last post I was doing a little refactoring and I decide to look at a few more things.

the_mighty_moose_god_by_sutsuki_sensei-d6x0kru.jpg

You may recall early on in my 'Character' class I had the following attribute


has 'class' =>(
is =>'ro',
isa =>'HashRef|Str',

);

Meaning that I could enter a hashref or a string for 'class'. Well there is a much better way to do this sort of thing and that is with 'coercion'.

This is accomplished with a Roles of Type Constraints for the items you want to coerce.

So our role will look like this


package RPG::ADD::Types;
use Moose::Role;
use Moose::Util::TypeConstraints;


subtype 'ClassIn',
as 'HashRef';

coerce 'ClassIn',
from 'Str',
via { { $_=>0} };


So I have created 'ClassIn' which is a subtupe of a the standard 'HashRef' and then I add in a coerce directive that tells Moose to take any 'Str' that is passed in and turn it into a hash as well.

The next part is to import this role into my 'Character' class like this


use Moose;
with 'RPG::ADD::Types';

and then change my 'class' attribute like this

has 'class' =>(
is =>'ro',
isa =>'ClassIn',
coerce => 1
);

then then both

my $str = RPG::ADD::Character->new({class=>{Fighter=>1,Thief=>8},...

and

my $str = RPG::ADD::Character->new({class=>Fighter,...

just work and I can change my BUILD so I no longer have to check if I am passing in a 'HashRef' so now it looks allot cleaner like this



$attr->{self} = $self;
$attr->{attr} = $attr;
apply_all_roles($self,("RPG::ADD::Class::Multi",=>$attr));

Well worth the little effort I put into it. I can see this coming in very handy when I eventually have to do arrays of equipped items such as weapons or even spells that a character might have memorized.

Sort of reminds me of 'constructors' in Java though this I think is a much better way to go about it.

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