1 package Moose::Util::TypeConstraints::Builtins;
6 use List::MoreUtils ();
7 use Scalar::Util qw( blessed looks_like_number reftype );
9 sub type { goto &Moose::Util::TypeConstraints::type }
10 sub subtype { goto &Moose::Util::TypeConstraints::subtype }
11 sub as { goto &Moose::Util::TypeConstraints::as }
12 sub where (&) { goto &Moose::Util::TypeConstraints::where }
13 sub optimize_as (&) { goto &Moose::Util::TypeConstraints::optimize_as }
14 sub inline_as (&) { goto &Moose::Util::TypeConstraints::inline_as }
19 type 'Any' # meta-type including all
23 subtype 'Item' # base type
29 => where { !defined($_) }
31 $_[0]->parent()->_inline_check($_[1])
32 . ' && !defined(' . $_[1] . ')'
37 => where { defined($_) }
39 $_[0]->parent()->_inline_check($_[1])
40 . ' && defined(' . $_[1] . ')'
45 => where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' }
47 $_[0]->parent()->_inline_check($_[1])
49 . '!defined(' . $_[1] . ') '
50 . '|| ' . $_[1] . ' eq "" '
51 . '|| "' . $_[1] . '" eq "1" '
52 . '|| "' . $_[1] . '" eq "0"'
60 $_[0]->parent()->_inline_check($_[1])
61 . ' && !ref(' . $_[1] . ')'
67 # no need to call parent - ref also checks for definedness
68 => inline_as { 'ref(' . $_[1] . ')' };
72 => where { ref(\$_) eq 'SCALAR' || ref(\(my $val = $_)) eq 'SCALAR' }
74 $_[0]->parent()->_inline_check($_[1])
76 . 'ref(\\' . $_[1] . ') eq "SCALAR"'
77 . ' || ref(\\(my $val = ' . $_[1] . ')) eq "SCALAR"'
83 => where { Scalar::Util::looks_like_number($_) }
85 # the long Str tests are redundant here
86 Moose::Util::TypeConstraints::find_type_constraint('Value')->_inline_check($_[1])
87 . ' && Scalar::Util::looks_like_number(' . $_[1] . ')'
92 => where { (my $val = $_) =~ /\A-?[0-9]+\z/ }
94 Moose::Util::TypeConstraints::find_type_constraint('Value')->_inline_check($_[1])
95 . ' && (my $val = ' . $_[1] . ') =~ /\A-?[0-9]+\z/'
100 => where { ref($_) eq 'CODE' }
101 => inline_as { 'ref(' . $_[1] . ') eq "CODE"' };
105 => where( \&_RegexpRef )
107 'Moose::Util::TypeConstraints::Builtins::_RegexpRef(' . $_[1] . ')'
112 => where { ref($_) eq 'GLOB' }
113 => inline_as { 'ref(' . $_[1] . ') eq "GLOB"' };
115 # NOTE: scalar filehandles are GLOB refs, but a GLOB ref is not always a
120 (ref($_) eq "GLOB" && Scalar::Util::openhandle($_))
121 || (blessed($_) && $_->isa("IO::Handle"));
124 '(ref(' . $_[1] . ') eq "GLOB" '
125 . '&& Scalar::Util::openhandle(' . $_[1] . ')) '
126 . '|| (Scalar::Util::blessed(' . $_[1] . ') '
127 . '&& ' . $_[1] . '->isa("IO::Handle"))'
132 => where { blessed($_) }
133 => inline_as { 'Scalar::Util::blessed(' . $_[1] . ')' };
135 # This type is deprecated.
138 => where { $_->can('does') };
142 => where { Class::MOP::is_class_loaded($_) }
143 # the long Str tests are redundant here
144 => inline_as { 'Class::MOP::is_class_loaded(' . $_[1] . ')' };
149 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
152 $_[0]->parent()->_inline_check($_[1])
154 . 'my $meta = Class::MOP::class_of(' . $_[1] . ');'
155 . '$meta && $meta->isa("Moose::Meta::Role");'
159 $registry->add_type_constraint(
160 Moose::Meta::TypeConstraint::Parameterizable->new(
162 package_defined_in => __PACKAGE__,
164 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
165 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
166 constraint_generator => sub {
167 my $type_parameter = shift;
168 my $check = $type_parameter->_compiled_type_constraint;
170 return $check->( ${$_} );
174 'ref(' . $_[1] . ') eq "SCALAR" '
175 . '|| ref(' . $_[1] . ') eq "REF"'
177 inline_generator => sub {
179 my $type_parameter = shift;
181 '(ref(' . $val . ') eq "SCALAR" || ref(' . $val . ') eq "REF") '
182 . '&& ' . $type_parameter->_inline_check('${(' . $val . ')}')
187 $registry->add_type_constraint(
188 Moose::Meta::TypeConstraint::Parameterizable->new(
190 package_defined_in => __PACKAGE__,
192 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
193 constraint => sub { ref($_) eq 'ARRAY' },
194 constraint_generator => sub {
195 my $type_parameter = shift;
196 my $check = $type_parameter->_compiled_type_constraint;
198 foreach my $x (@$_) {
199 ( $check->($x) ) || return;
204 inlined => sub { 'ref(' . $_[1] . ') eq "ARRAY"' },
205 inline_generator => sub {
207 my $type_parameter = shift;
211 . 'my $check = ' . $val . ';'
212 . 'ref($check) eq "ARRAY" '
213 . '&& &List::MoreUtils::all('
214 . 'sub { ' . $type_parameter->_inline_check('$_') . ' }, '
222 $registry->add_type_constraint(
223 Moose::Meta::TypeConstraint::Parameterizable->new(
225 package_defined_in => __PACKAGE__,
227 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
228 constraint => sub { ref($_) eq 'HASH' },
229 constraint_generator => sub {
230 my $type_parameter = shift;
231 my $check = $type_parameter->_compiled_type_constraint;
233 foreach my $x ( values %$_ ) {
234 ( $check->($x) ) || return;
239 inlined => sub { 'ref(' . $_[1] . ') eq "HASH"' },
240 inline_generator => sub {
242 my $type_parameter = shift;
246 . 'my $check = ' . $val . ';'
247 . 'ref($check) eq "HASH" '
248 . '&& &List::MoreUtils::all('
249 . 'sub { ' . $type_parameter->_inline_check('$_') . ' }, '
257 $registry->add_type_constraint(
258 Moose::Meta::TypeConstraint::Parameterizable->new(
260 package_defined_in => __PACKAGE__,
262 Moose::Util::TypeConstraints::find_type_constraint('Item'),
263 constraint => sub {1},
264 constraint_generator => sub {
265 my $type_parameter = shift;
266 my $check = $type_parameter->_compiled_type_constraint;
268 return 1 if not( defined($_) ) || $check->($_);
272 inlined => sub {'1'},
273 inline_generator => sub {
275 my $type_parameter = shift;
277 '!defined(' . $val . ') '
278 . '|| (' . $type_parameter->_inline_check($val) . ')'
290 =for pod_coverage_needs_some_pod