2 package Moose::Util::TypeConstraints;
8 use Sub::Name 'subname';
9 use Scalar::Util 'blessed';
11 our $VERSION = '0.02';
15 my $pkg = shift || caller();
16 return if $pkg eq ':no_export';
18 foreach my $export (qw(type subtype as where coerce from via)) {
19 *{"${pkg}::${export}"} = \&{"${export}"};
25 sub find_type_constraint {
26 my $type_name = shift;
30 sub register_type_constraint {
31 my ($type_name, $type_constraint) = @_;
32 $TYPES{$type_name} = $type_constraint;
35 sub dump_type_constraints {
37 $Data::Dumper::Deparse = 1;
38 Data::Dumper::Dumper(\%TYPES);
41 sub export_type_contstraints_as_functions {
44 foreach my $constraint (keys %TYPES) {
45 *{"${pkg}::${constraint}"} = $TYPES{$constraint};
52 sub find_type_coercion {
53 my $type_name = shift;
54 $COERCIONS{$type_name};
57 sub register_type_coercion {
58 my ($type_name, $type_coercion) = @_;
59 $COERCIONS{$type_name} = $type_coercion;
65 my ($name, $check) = @_;
66 my $full_name = caller() . "::${name}";
67 register_type_constraint($name => subname $full_name => sub {
69 return undef unless $check->($_[0]);
75 my ($name, $parent, $check) = @_;
77 my $full_name = caller() . "::${name}";
78 $parent = find_type_constraint($parent)
79 unless $parent && ref($parent) eq 'CODE';
80 register_type_constraint($name => subname $full_name => sub {
82 return undef unless defined $parent->($_[0]) && $check->($_[0]);
87 ($parent, $check) = ($name, $parent);
88 $parent = find_type_constraint($parent)
89 unless $parent && ref($parent) eq 'CODE';
90 return subname '__anon_subtype__' => sub {
92 return undef unless defined $parent->($_[0]) && $check->($_[0]);
99 my ($type_name, @coercion_map) = @_;
101 #warn Dumper \@coercion_map;
103 while (@coercion_map) {
104 my ($constraint_name, $action) = splice(@coercion_map, 0, 2);
105 my $constraint = find_type_constraint($constraint_name);
106 (defined $constraint)
107 || confess "Could not find the type constraint ($constraint_name)";
108 push @coercions => [ $constraint, $action ];
110 register_type_coercion($type_name, sub {
112 foreach my $coercion (@coercions) {
113 my ($constraint, $converter) = @$coercion;
114 if (defined $constraint->($thing)) {
116 return $converter->($thing);
124 sub from ($) { $_[0] }
125 sub where (&) { $_[0] }
126 sub via (&) { $_[0] }
128 # define some basic types
130 type Any => where { 1 };
132 type Value => where { !ref($_) };
133 type Ref => where { ref($_) };
135 subtype Int => as Value => where { Scalar::Util::looks_like_number($_) };
136 subtype Str => as Value => where { !Scalar::Util::looks_like_number($_) };
138 subtype ScalarRef => as Ref => where { ref($_) eq 'SCALAR' };
139 subtype ArrayRef => as Ref => where { ref($_) eq 'ARRAY' };
140 subtype HashRef => as Ref => where { ref($_) eq 'HASH' };
141 subtype CodeRef => as Ref => where { ref($_) eq 'CODE' };
142 subtype RegexpRef => as Ref => where { ref($_) eq 'Regexp' };
145 # blessed(qr/.../) returns true,.. how odd
146 subtype Object => as Ref => where { blessed($_) && blessed($_) ne 'Regexp' };
156 Moose::Util::TypeConstraints - Type constraint system for Moose
160 use Moose::Util::TypeConstraints;
162 type Num => where { Scalar::Util::looks_like_number($_) };
168 subtype NaturalLessThanTen
170 => where { $_ < 10 };
178 This module provides Moose with the ability to create type contraints
179 to be are used in both attribute definitions and for method argument
182 This is B<NOT> a type system for Perl 5.
184 This module also provides a simple hierarchy for Perl 5 types, this
185 could probably use some work, but it works for me at the moment.
199 Suggestions for improvement are welcome.
203 =head2 Type Constraint Registry
207 =item B<find_type_constraint ($type_name)>
209 =item B<register_type_constraint ($type_name, $type_constraint)>
211 =item B<find_type_coercion>
213 =item B<register_type_coercion>
215 =item B<export_type_contstraints_as_functions>
217 =item B<dump_type_constraints>
221 =head2 Type Constraint Constructors
241 =head2 Built-in Type Constraints
271 All complex software has bugs lurking in it, and this module is no
272 exception. If you find a bug please either email me, or add the bug
277 Stevan Little E<lt>stevan@iinteractive.comE<gt>
279 =head1 COPYRIGHT AND LICENSE
281 Copyright 2006 by Infinity Interactive, Inc.
283 L<http://www.iinteractive.com>
285 This library is free software; you can redistribute it and/or modify
286 it under the same terms as Perl itself.