Simple Clean Moose

So today, to start the new year right, I really am going to have a look at Moose coercion which I have been promissing to do since this post. So to refresh your memory I had created my types role and one type and added it to my accessor like this


has view => (
is => 'rw',
isa => 'View',
);

So what exactly does coercion do for us? Well as I had illustrated in a early post what I want it to do it take an input hash and then create an object from that hash to save us from typing up such unsightly things as

Database::Accessor->new({
view => Database::Accessor::View->new( {
name => 'person',
alias => 'me' })

by allowing us to this

Database::Accessor->new({
view => {
name => 'person',
alias => 'me'}

So all we need to do in in the types role add in coerce command like this

coerce 'View', from 'HashRef', via { Database::Accessor::View->new( %{$_} ) };

Which tells moose to coerce a new view from a HashRef with or via the 'Database::Accessor::View' class. I have always been impressed by the wording of the above as one can easily read what is going one unlike some other languages such as JAVA's 'assert', if memory serves me correctly, which uses the always confusing postfix notation which is much harder than the above to unserstand. To me Moose's coercion is the most clean and easy to read and understand or any of the coercinon styles I have seen in other languages.

Anyway back on topic, what I need net is simply to tell Moose to coerce the apporate Accessor.pm attribute like this


has view => (
is => 'rw',
isa => 'View',
++ coerce => 1,
);

and that is it. Now that is coercion in its most simple form and things can get as sophisticated and as customized as you like.

Now what that one little change above does warrant is me creating another test file for this as I want to keep my tests focused. So I have created 04_coerce.t to test the above.

Now for now all I really changed in this test was drop the use of the View class


--use_ok('Database::Accessor::View');

and then I droped the instantiation of the $view object and the ref test for that object

--my $view = Database::Accessor::View->new({name => 'person',alias => 'me'});
--ok( ref($view) eq 'Database::Accessor::View', "Person is a View" );

Next I changed the instantiation of the $address Accessor to this

my $address = Database::Accessor->new({
view => {name => 'person',
alias => 'me'},
elements => \@elements});

keep the same eval test checking to see If I could add in a bad clasee as before, Finally to make sure things are ok I test the view attribute to see if it is a View class like this

ok( ref($address->view()) eq 'Database::Accessor::View', "View is a Database::Accessor::View" );

Rerun and all pass yeah!.

So with exactly two lines of code I change my interface from a rather clumsy one a nice clean one.

Simple sweet and clean way to start the New Year.

washing-the-moose-rolf-lidberg-rl-60220-0.mpo.jpg

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