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($_) }
30 => inline_as { "! defined $_[1]" };
34 => where { defined($_) }
35 => inline_as { "defined $_[1]" };
39 => where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' }
40 => inline_as { qq{!defined($_[1]) || $_[1] eq "" || "$_[1]" eq '1' || "$_[1]" eq '0'} };
45 => optimize_as( \&_Value )
46 => inline_as { "defined $_[1] && ! ref $_[1]" };
51 => optimize_as( \&_Ref )
52 => inline_as { "ref $_[1]" };
56 => where { ref(\$_) eq 'SCALAR' }
57 => optimize_as( \&_Str )
59 return ( qq{defined $_[1]}
60 . qq{&& ( ref(\\ $_[1] ) eq 'SCALAR'}
61 . qq{ || ref(\\(my \$value = $_[1])) eq 'SCALAR')} );
66 => where { Scalar::Util::looks_like_number($_) }
67 => optimize_as( \&_Num )
68 => inline_as { "!ref $_[1] && Scalar::Util::looks_like_number($_[1])" };
72 => where { "$_" =~ /^-?[0-9]+$/ }
73 => optimize_as( \&_Int )
75 return ( qq{defined $_[1]}
77 . qq{&& ( my \$value = $_[1] ) =~ /\\A-?[0-9]+\\z/} );
82 => where { ref($_) eq 'CODE' }
83 => optimize_as( \&_CodeRef )
84 => inline_as { qq{ref $_[1] eq 'CODE'} };
88 => where( \&_RegexpRef )
89 => optimize_as( \&_RegexpRef )
90 => inline_as { "Moose::Util::TypeConstraints::Builtins::_RegexpRef( $_[1] )" };
94 => where { ref($_) eq 'GLOB' }
95 => optimize_as( \&_GlobRef )
96 => inline_as { qq{ref $_[1] eq 'GLOB'} };
98 # NOTE: scalar filehandles are GLOB refs, but a GLOB ref is not always a
103 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
105 => optimize_as( \&_FileHandle )
107 return ( qq{ref $_[1] eq 'GLOB'}
108 . qq{&& Scalar::Util::openhandle( $_[1] )}
109 . qq{or Scalar::Util::blessed( $_[1] ) && $_[1]->isa("IO::Handle")} );
114 => where { blessed($_) }
115 => optimize_as( \&_Object )
116 => inline_as { "Scalar::Util::blessed( $_[1] )" };
118 # This type is deprecated.
121 => where { $_->can('does') }
122 => optimize_as( \&_Role );
126 => where { Class::MOP::is_class_loaded($_) }
127 => optimize_as( \&_ClassName )
128 => inline_as { "Class::MOP::is_class_loaded( $_[1] )" };
133 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
135 => optimize_as( \&_RoleName )
137 return ( qq{Class::MOP::is_class_loaded( $_[1] )}
138 . qq{&& ( Class::MOP::class_of( $_[1] ) || return )}
139 . qq{ ->isa('Moose::Meta::Role')} );
142 $registry->add_type_constraint(
143 Moose::Meta::TypeConstraint::Parameterizable->new(
145 package_defined_in => __PACKAGE__,
147 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
148 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
149 optimized => \&_ScalarRef,
150 constraint_generator => sub {
151 my $type_parameter = shift;
152 my $check = $type_parameter->_compiled_type_constraint;
154 return $check->( ${$_} );
157 inlined => sub {qq{ref $_[1] eq 'SCALAR' || ref $_[1] eq 'REF'}},
158 inline_generator => sub {
160 my $type_parameter = shift;
162 return $type_parameter->_inline_check(
163 '${ (' . $val . ') }' );
168 $registry->add_type_constraint(
169 Moose::Meta::TypeConstraint::Parameterizable->new(
171 package_defined_in => __PACKAGE__,
173 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
174 constraint => sub { ref($_) eq 'ARRAY' },
175 optimized => \&_ArrayRef,
176 constraint_generator => sub {
177 my $type_parameter = shift;
178 my $check = $type_parameter->_compiled_type_constraint;
180 foreach my $x (@$_) {
181 ( $check->($x) ) || return;
186 inlined => sub {qq{ref $_[1] eq 'ARRAY'}},
187 inline_generator => sub {
189 my $type_parameter = shift;
192 '&List::MoreUtils::all( sub { '
193 . $type_parameter->_inline_check('$_')
199 $registry->add_type_constraint(
200 Moose::Meta::TypeConstraint::Parameterizable->new(
202 package_defined_in => __PACKAGE__,
204 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
205 constraint => sub { ref($_) eq 'HASH' },
206 optimized => \&_HashRef,
207 constraint_generator => sub {
208 my $type_parameter = shift;
209 my $check = $type_parameter->_compiled_type_constraint;
211 foreach my $x ( values %$_ ) {
212 ( $check->($x) ) || return;
217 inlined => sub {qq{ref $_[1] eq 'HASH'}},
218 inline_generator => sub {
220 my $type_parameter = shift;
223 '&List::MoreUtils::all( sub { '
224 . $type_parameter->_inline_check('$_')
225 . " }, values \%{$val} )";
230 $registry->add_type_constraint(
231 Moose::Meta::TypeConstraint::Parameterizable->new(
233 package_defined_in => __PACKAGE__,
235 Moose::Util::TypeConstraints::find_type_constraint('Item'),
236 constraint => sub {1},
237 constraint_generator => sub {
238 my $type_parameter = shift;
239 my $check = $type_parameter->_compiled_type_constraint;
241 return 1 if not( defined($_) ) || $check->($_);
245 inlined => sub {'1'},
246 inline_generator => sub {
248 my $type_parameter = shift;
251 "(! defined $val) || ("
252 . $type_parameter->_inline_check($val) . ')';
258 sub _Value { defined($_[0]) && !ref($_[0]) }
260 sub _Ref { ref($_[0]) }
262 # We might need to use a temporary here to flatten LVALUEs, for instance as in
263 # Str(substr($_,0,255)).
266 && ( ref(\ $_[0] ) eq 'SCALAR'
267 || ref(\(my $value = $_[0])) eq 'SCALAR')
270 sub _Num { !ref($_[0]) && looks_like_number($_[0]) }
272 # using a temporary here because regex matching promotes an IV to a PV,
273 # and that confuses some things (like JSON.pm)
276 defined($value) && !ref($value) && $value =~ /\A-?[0-9]+\z/
279 sub _ScalarRef { ref($_[0]) eq 'SCALAR' || ref($_[0]) eq 'REF' }
280 sub _ArrayRef { ref($_[0]) eq 'ARRAY' }
281 sub _HashRef { ref($_[0]) eq 'HASH' }
282 sub _CodeRef { ref($_[0]) eq 'CODE' }
283 sub _GlobRef { ref($_[0]) eq 'GLOB' }
285 # RegexpRef is implemented in Moose.xs
288 ref( $_[0] ) eq 'GLOB' && Scalar::Util::openhandle( $_[0] )
289 or blessed( $_[0] ) && $_[0]->isa("IO::Handle");
292 sub _Object { blessed($_[0]) }
295 Moose::Deprecated::deprecated(
296 feature => 'Role type',
298 'The Role type has been deprecated. Maybe you meant to create a RoleName type? This type be will be removed in Moose 2.0200.'
300 blessed( $_[0] ) && $_[0]->can('does');
304 return Class::MOP::is_class_loaded( $_[0] );
309 && ( Class::MOP::class_of( $_[0] ) || return )
310 ->isa('Moose::Meta::Role');