1 package Moose::Util::TypeConstraints::Builtins;
6 use Class::Load qw( is_class_loaded );
7 use List::MoreUtils ();
8 use Scalar::Util qw( blessed looks_like_number reftype );
10 sub type { goto &Moose::Util::TypeConstraints::type }
11 sub subtype { goto &Moose::Util::TypeConstraints::subtype }
12 sub as { goto &Moose::Util::TypeConstraints::as }
13 sub where (&) { goto &Moose::Util::TypeConstraints::where }
14 sub optimize_as (&) { goto &Moose::Util::TypeConstraints::optimize_as }
15 sub inline_as (&) { goto &Moose::Util::TypeConstraints::inline_as }
20 type 'Any' # meta-type including all
24 subtype 'Item' # base type
30 => where { !defined($_) }
32 '!defined(' . $_[1] . ')'
37 => where { defined($_) }
39 'defined(' . $_[1] . ')'
44 => where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' }
47 . '!defined(' . $_[1] . ') '
48 . '|| ' . $_[1] . ' eq "" '
49 . '|| (' . $_[1] . '."") eq "1" '
50 . '|| (' . $_[1] . '."") eq "0"'
58 $_[0]->parent()->_inline_check($_[1])
59 . ' && !ref(' . $_[1] . ')'
65 # no need to call parent - ref also checks for definedness
66 => inline_as { 'ref(' . $_[1] . ')' };
70 => where { ref(\$_) eq 'SCALAR' || ref(\(my $val = $_)) eq 'SCALAR' }
72 $_[0]->parent()->_inline_check($_[1])
74 . 'ref(\\' . $_[1] . ') eq "SCALAR"'
75 . ' || ref(\\(my $val = ' . $_[1] . ')) eq "SCALAR"'
79 my $value_type = Moose::Util::TypeConstraints::find_type_constraint('Value');
82 => where { Scalar::Util::looks_like_number($_) }
84 # the long Str tests are redundant here
85 $value_type->_inline_check($_[1])
86 . ' && Scalar::Util::looks_like_number(' . $_[1] . ')'
91 => where { (my $val = $_) =~ /\A-?[0-9]+\z/ }
93 $value_type->_inline_check($_[1])
94 . ' && (my $val = ' . $_[1] . ') =~ /\A-?[0-9]+\z/'
99 => where { ref($_) eq 'CODE' }
100 => inline_as { 'ref(' . $_[1] . ') eq "CODE"' };
104 => where( \&_RegexpRef )
106 'Moose::Util::TypeConstraints::Builtins::_RegexpRef(' . $_[1] . ')'
111 => where { ref($_) eq 'GLOB' }
112 => inline_as { 'ref(' . $_[1] . ') eq "GLOB"' };
114 # NOTE: scalar filehandles are GLOB refs, but a GLOB ref is not always a
119 (ref($_) eq "GLOB" && Scalar::Util::openhandle($_))
120 || (blessed($_) && $_->isa("IO::Handle"));
123 '(ref(' . $_[1] . ') eq "GLOB" '
124 . '&& Scalar::Util::openhandle(' . $_[1] . ')) '
125 . '|| (Scalar::Util::blessed(' . $_[1] . ') '
126 . '&& ' . $_[1] . '->isa("IO::Handle"))'
131 => where { blessed($_) }
132 => inline_as { 'Scalar::Util::blessed(' . $_[1] . ')' };
136 => where { is_class_loaded($_) }
137 # the long Str tests are redundant here
138 => inline_as { 'Class::Load::is_class_loaded(' . $_[1] . ')' };
143 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
146 $_[0]->parent()->_inline_check($_[1])
148 . 'my $meta = Class::MOP::class_of(' . $_[1] . ');'
149 . '$meta && $meta->isa("Moose::Meta::Role");'
153 $registry->add_type_constraint(
154 Moose::Meta::TypeConstraint::Parameterizable->new(
156 package_defined_in => __PACKAGE__,
158 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
159 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
160 constraint_generator => sub {
161 my $type_parameter = shift;
162 my $check = $type_parameter->_compiled_type_constraint;
164 return $check->( ${$_} );
168 'ref(' . $_[1] . ') eq "SCALAR" '
169 . '|| ref(' . $_[1] . ') eq "REF"'
171 inline_generator => sub {
173 my $type_parameter = shift;
175 '(ref(' . $val . ') eq "SCALAR" || ref(' . $val . ') eq "REF") '
176 . '&& ' . $type_parameter->_inline_check('${(' . $val . ')}')
181 $registry->add_type_constraint(
182 Moose::Meta::TypeConstraint::Parameterizable->new(
184 package_defined_in => __PACKAGE__,
186 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
187 constraint => sub { ref($_) eq 'ARRAY' },
188 constraint_generator => sub {
189 my $type_parameter = shift;
190 my $check = $type_parameter->_compiled_type_constraint;
192 foreach my $x (@$_) {
193 ( $check->($x) ) || return;
198 inlined => sub { 'ref(' . $_[1] . ') eq "ARRAY"' },
199 inline_generator => sub {
201 my $type_parameter = shift;
205 . 'my $check = ' . $val . ';'
206 . 'ref($check) eq "ARRAY" '
207 . '&& &List::MoreUtils::all('
208 . 'sub { ' . $type_parameter->_inline_check('$_') . ' }, '
216 $registry->add_type_constraint(
217 Moose::Meta::TypeConstraint::Parameterizable->new(
219 package_defined_in => __PACKAGE__,
221 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
222 constraint => sub { ref($_) eq 'HASH' },
223 constraint_generator => sub {
224 my $type_parameter = shift;
225 my $check = $type_parameter->_compiled_type_constraint;
227 foreach my $x ( values %$_ ) {
228 ( $check->($x) ) || return;
233 inlined => sub { 'ref(' . $_[1] . ') eq "HASH"' },
234 inline_generator => sub {
236 my $type_parameter = shift;
240 . 'my $check = ' . $val . ';'
241 . 'ref($check) eq "HASH" '
242 . '&& &List::MoreUtils::all('
243 . 'sub { ' . $type_parameter->_inline_check('$_') . ' }, '
251 $registry->add_type_constraint(
252 Moose::Meta::TypeConstraint::Parameterizable->new(
254 package_defined_in => __PACKAGE__,
256 Moose::Util::TypeConstraints::find_type_constraint('Item'),
257 constraint => sub {1},
258 constraint_generator => sub {
259 my $type_parameter = shift;
260 my $check = $type_parameter->_compiled_type_constraint;
262 return 1 if not( defined($_) ) || $check->($_);
266 inlined => sub {'1'},
267 inline_generator => sub {
269 my $type_parameter = shift;
271 '!defined(' . $val . ') '
272 . '|| (' . $type_parameter->_inline_check($val) . ')'
284 =for pod_coverage_needs_some_pod