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 '!defined(' . $_[1] . ')'
36 => where { defined($_) }
38 'defined(' . $_[1] . ')'
43 => where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' }
46 . '!defined(' . $_[1] . ') '
47 . '|| ' . $_[1] . ' eq "" '
48 . '|| (' . $_[1] . '."") eq "1" '
49 . '|| (' . $_[1] . '."") eq "0"'
57 $_[0]->parent()->_inline_check($_[1])
58 . ' && !ref(' . $_[1] . ')'
64 # no need to call parent - ref also checks for definedness
65 => inline_as { 'ref(' . $_[1] . ')' };
69 => where { ref(\$_) eq 'SCALAR' || ref(\(my $val = $_)) eq 'SCALAR' }
71 $_[0]->parent()->_inline_check($_[1])
73 . 'ref(\\' . $_[1] . ') eq "SCALAR"'
74 . ' || ref(\\(my $val = ' . $_[1] . ')) eq "SCALAR"'
78 my $value_type = Moose::Util::TypeConstraints::find_type_constraint('Value');
81 => where { Scalar::Util::looks_like_number($_) }
83 # the long Str tests are redundant here
84 $value_type->_inline_check($_[1])
85 . ' && Scalar::Util::looks_like_number(' . $_[1] . ')'
90 => where { (my $val = $_) =~ /\A-?[0-9]+\z/ }
92 $value_type->_inline_check($_[1])
93 . ' && (my $val = ' . $_[1] . ') =~ /\A-?[0-9]+\z/'
98 => where { ref($_) eq 'CODE' }
99 => inline_as { 'ref(' . $_[1] . ') eq "CODE"' };
103 => where( \&_RegexpRef )
105 'Moose::Util::TypeConstraints::Builtins::_RegexpRef(' . $_[1] . ')'
110 => where { ref($_) eq 'GLOB' }
111 => inline_as { 'ref(' . $_[1] . ') eq "GLOB"' };
113 # NOTE: scalar filehandles are GLOB refs, but a GLOB ref is not always a
118 (ref($_) eq "GLOB" && Scalar::Util::openhandle($_))
119 || (blessed($_) && $_->isa("IO::Handle"));
122 '(ref(' . $_[1] . ') eq "GLOB" '
123 . '&& Scalar::Util::openhandle(' . $_[1] . ')) '
124 . '|| (Scalar::Util::blessed(' . $_[1] . ') '
125 . '&& ' . $_[1] . '->isa("IO::Handle"))'
130 => where { blessed($_) }
131 => inline_as { 'Scalar::Util::blessed(' . $_[1] . ')' };
133 # This type is deprecated.
136 => where { $_->can('does') };
140 => where { Class::MOP::is_class_loaded($_) }
141 # the long Str tests are redundant here
142 => inline_as { 'Class::MOP::is_class_loaded(' . $_[1] . ')' };
147 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
150 $_[0]->parent()->_inline_check($_[1])
152 . 'my $meta = Class::MOP::class_of(' . $_[1] . ');'
153 . '$meta && $meta->isa("Moose::Meta::Role");'
157 $registry->add_type_constraint(
158 Moose::Meta::TypeConstraint::Parameterizable->new(
160 package_defined_in => __PACKAGE__,
162 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
163 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
164 constraint_generator => sub {
165 my $type_parameter = shift;
166 my $check = $type_parameter->_compiled_type_constraint;
168 return $check->( ${$_} );
172 'ref(' . $_[1] . ') eq "SCALAR" '
173 . '|| ref(' . $_[1] . ') eq "REF"'
175 inline_generator => sub {
177 my $type_parameter = shift;
179 '(ref(' . $val . ') eq "SCALAR" || ref(' . $val . ') eq "REF") '
180 . '&& ' . $type_parameter->_inline_check('${(' . $val . ')}')
185 $registry->add_type_constraint(
186 Moose::Meta::TypeConstraint::Parameterizable->new(
188 package_defined_in => __PACKAGE__,
190 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
191 constraint => sub { ref($_) eq 'ARRAY' },
192 constraint_generator => sub {
193 my $type_parameter = shift;
194 my $check = $type_parameter->_compiled_type_constraint;
196 foreach my $x (@$_) {
197 ( $check->($x) ) || return;
202 inlined => sub { 'ref(' . $_[1] . ') eq "ARRAY"' },
203 inline_generator => sub {
205 my $type_parameter = shift;
209 . 'my $check = ' . $val . ';'
210 . 'ref($check) eq "ARRAY" '
211 . '&& &List::MoreUtils::all('
212 . 'sub { ' . $type_parameter->_inline_check('$_') . ' }, '
220 $registry->add_type_constraint(
221 Moose::Meta::TypeConstraint::Parameterizable->new(
223 package_defined_in => __PACKAGE__,
225 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
226 constraint => sub { ref($_) eq 'HASH' },
227 constraint_generator => sub {
228 my $type_parameter = shift;
229 my $check = $type_parameter->_compiled_type_constraint;
231 foreach my $x ( values %$_ ) {
232 ( $check->($x) ) || return;
237 inlined => sub { 'ref(' . $_[1] . ') eq "HASH"' },
238 inline_generator => sub {
240 my $type_parameter = shift;
244 . 'my $check = ' . $val . ';'
245 . 'ref($check) eq "HASH" '
246 . '&& &List::MoreUtils::all('
247 . 'sub { ' . $type_parameter->_inline_check('$_') . ' }, '
255 $registry->add_type_constraint(
256 Moose::Meta::TypeConstraint::Parameterizable->new(
258 package_defined_in => __PACKAGE__,
260 Moose::Util::TypeConstraints::find_type_constraint('Item'),
261 constraint => sub {1},
262 constraint_generator => sub {
263 my $type_parameter = shift;
264 my $check = $type_parameter->_compiled_type_constraint;
266 return 1 if not( defined($_) ) || $check->($_);
270 inlined => sub {'1'},
271 inline_generator => sub {
273 my $type_parameter = shift;
275 '!defined(' . $val . ') '
276 . '|| (' . $type_parameter->_inline_check($val) . ')'
288 =for pod_coverage_needs_some_pod