X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FUtil%2FTypeConstraints.pm;h=eb5524d6ecd4402d87fae2264cbbb483376177e5;hb=01bf41120a30b2360c0f544a044467ab26731459;hp=f21e348a9e253b1585cfb358966ae52ffd520074;hpb=e90c03d0a4c255314c81687b980b844f8bc48bbe;p=gitmo%2FMoose.git diff --git a/lib/Moose/Util/TypeConstraints.pm b/lib/Moose/Util/TypeConstraints.pm index f21e348..eb5524d 100644 --- a/lib/Moose/Util/TypeConstraints.pm +++ b/lib/Moose/Util/TypeConstraints.pm @@ -10,12 +10,14 @@ use Scalar::Util 'blessed'; our $VERSION = '0.02'; +use Moose::Meta::TypeConstraint; + sub import { shift; my $pkg = shift || caller(); return if $pkg eq ':no_export'; no strict 'refs'; - foreach my $export (qw(type subtype coerce as where to)) { + foreach my $export (qw(type subtype as where coerce from via)) { *{"${pkg}::${export}"} = \&{"${export}"}; } } @@ -29,28 +31,39 @@ sub import { sub register_type_constraint { my ($type_name, $type_constraint) = @_; - $TYPES{$type_name} = $type_constraint; + (not exists $TYPES{$type_name}) + || confess "The type constraint '$type_name' has already been registered"; + $TYPES{$type_name} = Moose::Meta::TypeConstraint->new( + name => $type_name, + constraint_code => $type_constraint + ); + } + + sub dump_type_constraints { + require Data::Dumper; + $Data::Dumper::Deparse = 1; + Data::Dumper::Dumper(\%TYPES); } sub export_type_contstraints_as_functions { my $pkg = caller(); no strict 'refs'; foreach my $constraint (keys %TYPES) { - *{"${pkg}::${constraint}"} = $TYPES{$constraint}; + *{"${pkg}::${constraint}"} = $TYPES{$constraint}->constraint_code; } } -} -{ - my %COERCIONS; sub find_type_coercion { my $type_name = shift; - $COERCIONS{$type_name}; + $TYPES{$type_name}->coercion_code; } sub register_type_coercion { my ($type_name, $type_coercion) = @_; - $COERCIONS{$type_name} = $type_coercion; + my $type = $TYPES{$type_name}; + (!$type->has_coercion) + || confess "The type coercion for '$type_name' has already been registered"; + $type->set_coercion_code($type_coercion); } } @@ -59,7 +72,6 @@ sub type ($$) { my ($name, $check) = @_; my $full_name = caller() . "::${name}"; register_type_constraint($name => subname $full_name => sub { - return find_type_constraint($name) unless defined $_[0]; local $_ = $_[0]; return undef unless $check->($_[0]); $_[0]; @@ -70,10 +82,9 @@ sub subtype ($$;$) { my ($name, $parent, $check) = @_; if (defined $check) { my $full_name = caller() . "::${name}"; - $parent = find_type_constraint($parent) + $parent = find_type_constraint($parent)->constraint_code unless $parent && ref($parent) eq 'CODE'; - register_type_constraint($name => subname $full_name => sub { - return find_type_constraint($name) unless defined $_[0]; + register_type_constraint($name => subname $full_name => sub { local $_ = $_[0]; return undef unless defined $parent->($_[0]) && $check->($_[0]); $_[0]; @@ -81,7 +92,7 @@ sub subtype ($$;$) { } else { ($parent, $check) = ($name, $parent); - $parent = find_type_constraint($parent) + $parent = find_type_constraint($parent)->constraint_code unless $parent && ref($parent) eq 'CODE'; return subname '__anon_subtype__' => sub { local $_ = $_[0]; @@ -91,12 +102,14 @@ sub subtype ($$;$) { } } -sub coerce { +sub coerce ($@) { my ($type_name, @coercion_map) = @_; + #use Data::Dumper; + #warn Dumper \@coercion_map; my @coercions; while (@coercion_map) { my ($constraint_name, $action) = splice(@coercion_map, 0, 2); - my $constraint = find_type_constraint($constraint_name); + my $constraint = find_type_constraint($constraint_name)->constraint_code; (defined $constraint) || confess "Could not find the type constraint ($constraint_name)"; push @coercions => [ $constraint, $action ]; @@ -106,6 +119,7 @@ sub coerce { foreach my $coercion (@coercions) { my ($constraint, $converter) = @$coercion; if (defined $constraint->($thing)) { + local $_ = $thing; return $converter->($thing); } } @@ -114,8 +128,9 @@ sub coerce { } sub as ($) { $_[0] } +sub from ($) { $_[0] } sub where (&) { $_[0] } -sub to (&) { $_[0] } +sub via (&) { $_[0] } # define some basic types @@ -160,6 +175,10 @@ Moose::Util::TypeConstraints - Type constraint system for Moose subtype NaturalLessThanTen => as Natural => where { $_ < 10 }; + + coerce Num + => from Str + => via { 0+$_ }; =head1 DESCRIPTION @@ -169,10 +188,6 @@ validation. This is B a type system for Perl 5. -The type and subtype constraints are basically functions which will -validate their first argument. If called with no arguments, they will -return themselves (this is syntactic sugar for Moose attributes). - This module also provides a simple hierarchy for Perl 5 types, this could probably use some work, but it works for me at the moment. @@ -206,6 +221,8 @@ Suggestions for improvement are welcome. =item B +=item B + =back =head2 Type Constraint Constructors @@ -222,7 +239,9 @@ Suggestions for improvement are welcome. =item B -=item B +=item B + +=item B =back