1 package Moose::Util::TypeConstraints::Builtins;
6 use Scalar::Util qw( blessed looks_like_number reftype );
8 sub type { goto &Moose::Util::TypeConstraints::type }
9 sub subtype { goto &Moose::Util::TypeConstraints::subtype }
10 sub as { goto &Moose::Util::TypeConstraints::as }
11 sub where (&) { goto &Moose::Util::TypeConstraints::where }
12 sub optimize_as (&) { goto &Moose::Util::TypeConstraints::optimize_as }
13 sub inline_as (&) { goto &Moose::Util::TypeConstraints::inline_as }
18 type 'Any' # meta-type including all
22 subtype 'Item' # base-type
28 => where { !defined($_) }
29 => inline_as { "! defined $_[0]" };
33 => where { defined($_) }
34 => inline_as { "defined $_[0]" };
38 => where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' }
39 => inline_as { qq{!defined($_[0]) || $_[0] eq "" || "$_[0]" eq '1' || "$_[0]" eq '0'} };
44 => optimize_as( \&_Value )
45 => inline_as { "defined $_[0] && ! ref $_[0]" };
50 => optimize_as( \&_Ref )
51 => inline_as { "ref $_[0]" };
55 => where { ref(\$_) eq 'SCALAR' }
56 => optimize_as( \&_Str )
58 return ( qq{defined $_[0]}
59 . qq{&& ( ref(\\ $_[0] ) eq 'SCALAR'}
60 . qq{ || ref(\\(my \$value = $_[0])) eq 'SCALAR')} );
65 => where { Scalar::Util::looks_like_number($_) }
66 => optimize_as( \&_Num )
67 => inline_as { "!ref $_[0] && Scalar::Util::looks_like_number($_[0])" };
71 => where { "$_" =~ /^-?[0-9]+$/ }
72 => optimize_as( \&_Int )
74 return ( qq{defined $_[0]}
76 . qq{&& ( my \$value = $_[0] ) =~ /\\A-?[0-9]+\\z/} );
81 => where { ref($_) eq 'CODE' }
82 => optimize_as( \&_CodeRef )
83 => inline_as { qq{ref $_[0] eq 'CODE'} };
87 => where( \&_RegexpRef )
88 => optimize_as( \&_RegexpRef )
89 => inline_as { "Moose::Util::TypeConstraints::Builtins::_RegexpRef( $_[0] )" };
93 => where { ref($_) eq 'GLOB' }
94 => optimize_as( \&_GlobRef )
95 => inline_as { qq{ref $_[0] eq 'GLOB'} };
97 # NOTE: scalar filehandles are GLOB refs, but a GLOB ref is not always a
102 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
104 => optimize_as( \&_FileHandle )
106 return ( qq{ref $_[0] eq 'GLOB'}
107 . qq{&& Scalar::Util::openhandle( $_[0] )}
108 . qq{or Scalar::Util::blessed( $_[0] ) && $_[0]->isa("IO::Handle")} );
113 => where { blessed($_) }
114 => optimize_as( \&_Object )
115 => inline_as { "Scalar::Util::blessed( $_[0] )" };
117 # This type is deprecated.
120 => where { $_->can('does') }
121 => optimize_as( \&_Role );
125 => where { Class::MOP::is_class_loaded($_) }
126 => optimize_as( \&_ClassName )
127 => inline_as { "Class::MOP::is_class_loaded( $_[0] )" };
132 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
134 => optimize_as( \&_RoleName )
136 return ( qq{Class::MOP::is_class_loaded( $_[0] )}
137 . qq{&& ( Class::MOP::class_of( $_[0] ) || return )}
138 . qq{ ->isa('Moose::Meta::Role')} );
141 $registry->add_type_constraint(
142 Moose::Meta::TypeConstraint::Parameterizable->new(
144 package_defined_in => __PACKAGE__,
146 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
147 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
148 optimized => \&_ScalarRef,
149 constraint_generator => sub {
150 my $type_parameter = shift;
151 my $check = $type_parameter->_compiled_type_constraint;
153 return $check->( ${$_} );
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 'ARRAY' },
166 optimized => \&_ArrayRef,
167 constraint_generator => sub {
168 my $type_parameter = shift;
169 my $check = $type_parameter->_compiled_type_constraint;
171 foreach my $x (@$_) {
172 ( $check->($x) ) || return;
180 $registry->add_type_constraint(
181 Moose::Meta::TypeConstraint::Parameterizable->new(
183 package_defined_in => __PACKAGE__,
185 Moose::Util::TypeConstraints::find_type_constraint('Ref'),
186 constraint => sub { ref($_) eq 'HASH' },
187 optimized => \&_HashRef,
188 constraint_generator => sub {
189 my $type_parameter = shift;
190 my $check = $type_parameter->_compiled_type_constraint;
192 foreach my $x ( values %$_ ) {
193 ( $check->($x) ) || return;
201 $registry->add_type_constraint(
202 Moose::Meta::TypeConstraint::Parameterizable->new(
204 package_defined_in => __PACKAGE__,
206 Moose::Util::TypeConstraints::find_type_constraint('Item'),
207 constraint => sub {1},
208 constraint_generator => sub {
209 my $type_parameter = shift;
210 my $check = $type_parameter->_compiled_type_constraint;
212 return 1 if not( defined($_) ) || $check->($_);
220 sub _Value { defined($_[0]) && !ref($_[0]) }
222 sub _Ref { ref($_[0]) }
224 # We might need to use a temporary here to flatten LVALUEs, for instance as in
225 # Str(substr($_,0,255)).
228 && ( ref(\ $_[0] ) eq 'SCALAR'
229 || ref(\(my $value = $_[0])) eq 'SCALAR')
232 sub _Num { !ref($_[0]) && looks_like_number($_[0]) }
234 # using a temporary here because regex matching promotes an IV to a PV,
235 # and that confuses some things (like JSON.pm)
238 defined($value) && !ref($value) && $value =~ /\A-?[0-9]+\z/
241 sub _ScalarRef { ref($_[0]) eq 'SCALAR' || ref($_[0]) eq 'REF' }
242 sub _ArrayRef { ref($_[0]) eq 'ARRAY' }
243 sub _HashRef { ref($_[0]) eq 'HASH' }
244 sub _CodeRef { ref($_[0]) eq 'CODE' }
245 sub _GlobRef { ref($_[0]) eq 'GLOB' }
247 # RegexpRef is implemented in Moose.xs
250 ref( $_[0] ) eq 'GLOB' && Scalar::Util::openhandle( $_[0] )
251 or blessed( $_[0] ) && $_[0]->isa("IO::Handle");
254 sub _Object { blessed($_[0]) }
257 Moose::Deprecated::deprecated(
258 feature => 'Role type',
260 'The Role type has been deprecated. Maybe you meant to create a RoleName type? This type be will be removed in Moose 2.0200.'
262 blessed( $_[0] ) && $_[0]->can('does');
266 return Class::MOP::is_class_loaded( $_[0] );
271 && ( Class::MOP::class_of( $_[0] ) || return )
272 ->isa('Moose::Meta::Role');