package Human; use Moose; use Moose::Util::TypeConstraints; use List::MoreUtils qw( zip ); use Crypt::Random qw( makerandom ); use Human::EyeColor; subtype 'EyeColor' => as 'Object' => where { $_->isa('Human::EyeColor') }; coerce 'EyeColor' => from 'ArrayRef' => via { my @genes = qw( bey2_1 bey2_2 gey_1 gey_2 ); return Human::EyeColor->new( zip( @genes, @$_ ) ); }; subtype 'Gender' => as 'Str' => where { $_ =~ m{^[mf]$}s }; has 'gender' => ( is => 'ro', isa => 'Gender' ); has 'eye_color' => ( is => 'ro', isa => 'EyeColor', coerce => 1 ); has 'mother' => ( is => 'ro', isa => 'Human' ); has 'father' => ( is => 'ro', isa => 'Human' ); use overload '+' => \&_overload_add, fallback => 1; sub _overload_add { my ($one, $two) = @_; die('Only male and female humans may have children') if ($one->gender() eq $two->gender()); my ( $mother, $father ) = ( $one->gender eq 'f' ? ($one, $two) : ($two, $one) ); my $gender = 'f'; $gender = 'm' if (makerandom( Size => 1, Strength => 1, Uniform => 1 )); return Human->new( gender => $gender, eye_color => ( $one->eye_color() + $two->eye_color() ), mother => $mother, father => $father, ); } 1;