I am trying to find a decent design pattern for Moose validation of
user input. All the Moose examples I have found either assume that 
the data is correct or else dies.

Example:
package Address ;
use Moose;
use Moose::Util::TypeConstraints;

subtype 'Email',
      as 'Str',
      where { $_ =~ m!@! },
      message { "The email you provided, $_, was not a valid email" };

package Person ; 
use Moose ; 
has 'email' => (is => 'rw', isa => 'Email', required => 1) ;

package main ;

my $f = Person->new(email => 'xa.com') ; 

The above pattern is much like the examples in the manual. 

>From an OOP perspective, it seems to me that the validation performed
by the subtype should be part of the class and not something that is
just floating around. There is also no reasonable way to trap the
error, and report back to the user that there was an error. And I am
not a fan of try/catch.

I have come up with the following design pattern to allow validation.
The idea is to create a class, Email, which accepts any data. If the
data is good, error is set to 0.  If the error is set to 1, it also
changes the package name so that if it is passed onwards the program
dies.

package EmailRole ; 
use Moose::Role ; 

has 'email' => ( is => 'rw', isa => 'Str',required => 1) ;   
has 'error' => ( is => 'rw', isa => 'Str', default => 0) ;   

sub BUILD { 
    my $my = shift ;
    if ($my->email !~ m!@!) { 
        $my->error(1) ; 
        bless $my, 'EmailError'; 
    } 
    return $my ;
} 
no Moose ; 

package Email ;
use Moose ; 
with 'EmailRole' ; 

package EmailError ;
use Moose ; 
with 'EmailRole'; 

no Moose ; 

package Person ; 
use Moose ; 
has 'email' => ( is => 'ro', isa => 'Email' ) ; 

package main ; 
my $emailGood = Email->new(email => 'x...@yyy.com') ;
my $personGood = Person->new(email => $emailGood) ;

my $emailBad = Email->new(email => 'xxx') ; 
print "Bad Person" if $emailBad->error ; 
# And if we insist on proceeding, the following line will fail.
my $personBad = Person->new(email => $emailBad) ;

What I would like is some feedback 
a) what are the pitfalls of this design.
b) are there any better designs?






Reply via email to