use Moose;
use Moose::Util::TypeConstraints ();
use Scalar::Util qw(blessed);
-
+use Data::Dump;
+use Digest::MD5;
+
extends 'Moose::Meta::TypeConstraint';
=head1 NAME
Moose->throw_error('Too Many Args! Two are allowed.') if @_;
- return $class->new(
- name => $self->_generate_subtype_name($arg1, $arg2),
- parent => $self,
- constraint => $self->constraint,
- parent_type_constraint=>$arg1,
- constraining_value_type_constraint => $arg2,
- );
+ my $name = $self->_generate_subtype_name($arg1, $arg2);
+ if(my $exists = Moose::Util::TypeConstraints::find_type_constraint($name)) {
+ return $exists;
+ } else {
+ my $type_constraint = $class->new(
+ name => $name,
+ parent => $self,
+ constraint => $self->constraint,
+ parent_type_constraint=>$arg1,
+ constraining_value_type_constraint => $arg2,
+ );
+ Moose::Util::TypeConstraints::get_type_constraint_registry->add_type_constraint($type_constraint);
+ return $type_constraint;
+ }
} else {
Moose->throw_error("$arg1 is not a type of: ".$self->constraining_value_type_constraint->name)
unless $arg1->is_a_type_of($self->constraining_value_type_constraint);
- return $class->new(
- name => $self->_generate_subtype_name($self->parent_type_constraint, $arg1),
- parent => $self,
- constraint => $self->constraint,
- parent_type_constraint=>$self->parent_type_constraint,
- constraining_value_type_constraint => $arg1,
- );
+ my $name = $self->_generate_subtype_name($self->parent_type_constraint, $arg1);
+ if(my $exists = Moose::Util::TypeConstraints::find_type_constraint($name)) {
+ return $exists;
+ } else {
+ my $type_constraint = $class->new(
+ name => $name,
+ parent => $self,
+ constraint => $self->constraint,
+ parent_type_constraint=>$self->parent_type_constraint,
+ constraining_value_type_constraint => $arg1,
+ );
+ Moose::Util::TypeConstraints::get_type_constraint_registry->add_type_constraint($type_constraint);
+ return $type_constraint;
+ }
}
} else {
my $args;
if(my $err = $self->constraining_value_type_constraint->validate($args)) {
Moose->throw_error($err);
} else {
- ## TODO memorize or do a registry lookup on the name as an optimization
- return $class->new(
- name => $self->name."[$args]",
- parent => $self,
- constraint => $self->constraint,
- constraining_value => $args,
- parent_type_constraint=>$self->parent_type_constraint,
- constraining_value_type_constraint => $self->constraining_value_type_constraint,
- );
+
+ my $sig = $args;
+ if(ref $sig) {
+ $sig = Digest::MD5::md5_hex(Data::Dump::dump($args));
+ }
+ my $name = $self->name."[$sig]";
+ if(my $exists = Moose::Util::TypeConstraints::find_type_constraint($name)) {
+ return $exists;
+ } else {
+ my $type_constraint = $class->new(
+ name => $name,
+ parent => $self,
+ constraint => $self->constraint,
+ constraining_value => $args,
+ parent_type_constraint=>$self->parent_type_constraint,
+ constraining_value_type_constraint => $self->constraining_value_type_constraint,
+ );
+ Moose::Util::TypeConstraints::get_type_constraint_registry->add_type_constraint($type_constraint);
+ return $type_constraint;
+ }
}
}
}
};
};
+around 'coerce' => sub {
+ my ($coerce, $self, @args) = @_;
+ if($self->coercion) {
+ if(my $value = $self->$coerce(@args)) {
+ return $value;
+ }
+ }
+ return $self->parent->coerce(@args);
+};
+
=head2 get_message
Give you a better peek into what's causing the error.
-use Test::More tests=>9; {
+use Test::More tests=>14; {
use strict;
use warnings;
ok !OlderThanAge([older_than=>1])->check('aaa'), '"aaa" not an int';
ok !OlderThanAge([older_than=>10])->check(9), '9 is not older than 10';
+ my $a = OlderThanAge([older_than=>1]);
+
+ coerce $a,
+ from ArrayRef,
+ via {
+ my ($arrayref, $constraining_value) = @_;
+ my $age;
+ $age += $_ for @$arrayref;
+ return $age;
+ };
+
+ is $a->coerce([1,2,3]), 6, 'Got expected Value';
+
coerce OlderThanAge,
+ from HashRef,
+ via {
+ my ($hashref, $constraining_value) = @_;
+ return keys %$hashref;
+ };
+
+ coerce OlderThanAge([older_than=>5]),
from ArrayRef,
via {
my ($arrayref, $constraining_value) = @_;
$age += $_ for @$arrayref;
return $age;
};
-
- #warn OlderThanAge([older_than=>1])->coerce([1,2,3,4]);
+
+ is OlderThanAge->name, 'main::OlderThanAge',
+ 'Got corect name for OlderThanAge';
+ is OlderThanAge([older_than=>5])->coerce([1..10]), 55,
+ 'Coerce works';
+ like OlderThanAge([older_than=>2])->name, qr/main::OlderThanAge\[/,
+ 'Got correct name for OlderThanAge([older_than=>2])';
+ is OlderThanAge([older_than=>2])->coerce({a=>1,b=>2,c=>3,d=>4}), 4,
+ 'inherited Coerce works';
+
+
}
\ No newline at end of file