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.


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},...


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;

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