← Index
Performance Profile   « block view • line view • sub view »
For t/test-parsing
  Run on Sun Nov 14 09:49:57 2010
Reported on Sun Nov 14 09:50:08 2010

File /usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm
Statements Executed 1061
Total Time 0.0117003 seconds
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
17171541µs4.50msMoose::Util::TypeConstraints::::subtypeMoose::Util::TypeConstraints::subtype
1821499µs4.06msMoose::Util::TypeConstraints::::_create_type_constraintMoose::Util::TypeConstraints::_create_type_constraint
4173352µs1.28msMoose::Util::TypeConstraints::::find_type_constraintMoose::Util::TypeConstraints::find_type_constraint
2311195µs1.03msMoose::Util::TypeConstraints::::find_or_parse_type_constraintMoose::Util::TypeConstraints::find_or_parse_type_constraint
711135µs1.53msMoose::Util::TypeConstraints::::create_class_type_constraintMoose::Util::TypeConstraints::create_class_type_constraint
2322130µs1.16msMoose::Util::TypeConstraints::::find_or_create_isa_type_constraintMoose::Util::TypeConstraints::find_or_create_isa_type_constraint
2311126µs126µsMoose::Util::TypeConstraints::::normalize_type_constraint_nameMoose::Util::TypeConstraints::normalize_type_constraint_name
1717193µs93µsMoose::Util::TypeConstraints::::whereMoose::Util::TypeConstraints::where
1717193µs93µsMoose::Util::TypeConstraints::::asMoose::Util::TypeConstraints::as
71175µs333µsMoose::Util::TypeConstraints::::register_type_constraintMoose::Util::TypeConstraints::register_type_constraint
1313158µs58µsMoose::Util::TypeConstraints::::optimize_asMoose::Util::TypeConstraints::optimize_as
71153µs1.91msMoose::Util::TypeConstraints::::class_typeMoose::Util::TypeConstraints::class_type
11123µs392µsMoose::Util::TypeConstraints::::typeMoose::Util::TypeConstraints::type
11113µs18µsMoose::Util::TypeConstraints::::list_all_type_constraintsMoose::Util::TypeConstraints::list_all_type_constraints
0000s0sMoose::Util::TypeConstraints::::BEGINMoose::Util::TypeConstraints::BEGIN
0000s0sMoose::Util::TypeConstraints::::__ANON__[:278]Moose::Util::TypeConstraints::__ANON__[:278]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:315]Moose::Util::TypeConstraints::__ANON__[:315]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:327]Moose::Util::TypeConstraints::__ANON__[:327]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:707]Moose::Util::TypeConstraints::__ANON__[:707]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:710]Moose::Util::TypeConstraints::__ANON__[:710]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:711]Moose::Util::TypeConstraints::__ANON__[:711]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:714]Moose::Util::TypeConstraints::__ANON__[:714]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:716]Moose::Util::TypeConstraints::__ANON__[:716]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:719]Moose::Util::TypeConstraints::__ANON__[:719]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:71]Moose::Util::TypeConstraints::__ANON__[:71]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:722]Moose::Util::TypeConstraints::__ANON__[:722]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:726]Moose::Util::TypeConstraints::__ANON__[:726]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:729]Moose::Util::TypeConstraints::__ANON__[:729]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:732]Moose::Util::TypeConstraints::__ANON__[:732]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:734]Moose::Util::TypeConstraints::__ANON__[:734]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:737]Moose::Util::TypeConstraints::__ANON__[:737]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:745]Moose::Util::TypeConstraints::__ANON__[:745]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:751]Moose::Util::TypeConstraints::__ANON__[:751]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:755]Moose::Util::TypeConstraints::__ANON__[:755]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:758]Moose::Util::TypeConstraints::__ANON__[:758]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:761]Moose::Util::TypeConstraints::__ANON__[:761]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:766]Moose::Util::TypeConstraints::__ANON__[:766]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:777]Moose::Util::TypeConstraints::__ANON__[:777]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:785]Moose::Util::TypeConstraints::__ANON__[:785]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:786]Moose::Util::TypeConstraints::__ANON__[:786]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:795]Moose::Util::TypeConstraints::__ANON__[:795]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:806]Moose::Util::TypeConstraints::__ANON__[:806]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:807]Moose::Util::TypeConstraints::__ANON__[:807]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:816]Moose::Util::TypeConstraints::__ANON__[:816]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:827]Moose::Util::TypeConstraints::__ANON__[:827]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:828]Moose::Util::TypeConstraints::__ANON__[:828]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:837]Moose::Util::TypeConstraints::__ANON__[:837]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:844]Moose::Util::TypeConstraints::__ANON__[:844]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:845]Moose::Util::TypeConstraints::__ANON__[:845]
0000s0sMoose::Util::TypeConstraints::::_confessMoose::Util::TypeConstraints::_confess
0000s0sMoose::Util::TypeConstraints::::_create_parameterized_type_constraintMoose::Util::TypeConstraints::_create_parameterized_type_constraint
0000s0sMoose::Util::TypeConstraints::::_detect_parameterized_type_constraintMoose::Util::TypeConstraints::_detect_parameterized_type_constraint
0000s0sMoose::Util::TypeConstraints::::_detect_type_constraint_unionMoose::Util::TypeConstraints::_detect_type_constraint_union
0000s0sMoose::Util::TypeConstraints::::_install_type_coercionsMoose::Util::TypeConstraints::_install_type_coercions
0000s0sMoose::Util::TypeConstraints::::_parse_parameterized_type_constraintMoose::Util::TypeConstraints::_parse_parameterized_type_constraint
0000s0sMoose::Util::TypeConstraints::::_parse_type_constraint_unionMoose::Util::TypeConstraints::_parse_type_constraint_union
0000s0sMoose::Util::TypeConstraints::::_throw_errorMoose::Util::TypeConstraints::_throw_error
0000s0sMoose::Util::TypeConstraints::::add_parameterizable_typeMoose::Util::TypeConstraints::add_parameterizable_type
0000s0sMoose::Util::TypeConstraints::::coerceMoose::Util::TypeConstraints::coerce
0000s0sMoose::Util::TypeConstraints::::create_duck_type_constraintMoose::Util::TypeConstraints::create_duck_type_constraint
0000s0sMoose::Util::TypeConstraints::::create_enum_type_constraintMoose::Util::TypeConstraints::create_enum_type_constraint
0000s0sMoose::Util::TypeConstraints::::create_parameterized_type_constraintMoose::Util::TypeConstraints::create_parameterized_type_constraint
0000s0sMoose::Util::TypeConstraints::::create_role_type_constraintMoose::Util::TypeConstraints::create_role_type_constraint
0000s0sMoose::Util::TypeConstraints::::create_type_constraint_unionMoose::Util::TypeConstraints::create_type_constraint_union
0000s0sMoose::Util::TypeConstraints::::duck_typeMoose::Util::TypeConstraints::duck_type
0000s0sMoose::Util::TypeConstraints::::enumMoose::Util::TypeConstraints::enum
0000s0sMoose::Util::TypeConstraints::::export_type_constraints_as_functionsMoose::Util::TypeConstraints::export_type_constraints_as_functions
0000s0sMoose::Util::TypeConstraints::::find_or_create_does_type_constraintMoose::Util::TypeConstraints::find_or_create_does_type_constraint
0000s0sMoose::Util::TypeConstraints::::find_or_create_type_constraintMoose::Util::TypeConstraints::find_or_create_type_constraint
0000s0sMoose::Util::TypeConstraints::::fromMoose::Util::TypeConstraints::from
0000s0sMoose::Util::TypeConstraints::::get_all_parameterizable_typesMoose::Util::TypeConstraints::get_all_parameterizable_types
0000s0sMoose::Util::TypeConstraints::::get_type_constraint_registryMoose::Util::TypeConstraints::get_type_constraint_registry
0000s0sMoose::Util::TypeConstraints::::list_all_builtin_type_constraintsMoose::Util::TypeConstraints::list_all_builtin_type_constraints
0000s0sMoose::Util::TypeConstraints::::match_on_typeMoose::Util::TypeConstraints::match_on_type
0000s0sMoose::Util::TypeConstraints::::maybe_typeMoose::Util::TypeConstraints::maybe_type
0000s0sMoose::Util::TypeConstraints::::messageMoose::Util::TypeConstraints::message
0000s0sMoose::Util::TypeConstraints::::role_typeMoose::Util::TypeConstraints::role_type
0000s0sMoose::Util::TypeConstraints::::viaMoose::Util::TypeConstraints::via
LineStmts.Exclusive
Time
Avg.Code
1
2package Moose::Util::TypeConstraints;
3
4326µs9µsuse Carp ();
5337µs12µsuse List::MoreUtils qw( all any );
# spent 51µs making 1 call to Exporter::import
6325µs8µsuse Scalar::Util qw( blessed reftype );
# spent 42µs making 1 call to Exporter::import
7392µs31µsuse Moose::Exporter;
# spent 35µs making 1 call to Moose::Exporter::import
8
911µs1µsour $VERSION = '1.15';
10135µs35µs$VERSION = eval $VERSION;
111900ns900nsour $AUTHORITY = 'cpan:STEVAN';
12
13## --------------------------------------------------------
14# Prototyped subs must be predeclared because we have a
15# circular dependency with Moose::Meta::Attribute et. al.
16# so in case of us being use'd first the predeclaration
17# ensures the prototypes are in scope when consumers are
18# compiled.
19
20# dah sugah!
21sub where (&);
22sub via (&);
23sub message (&);
24sub optimize_as (&);
25
26## --------------------------------------------------------
27
28330µs10µsuse Moose::Deprecated;
29326µs9µsuse Moose::Meta::TypeConstraint;
# spent 4µs making 1 call to import
303131µs44µsuse Moose::Meta::TypeConstraint::Union;
# spent 3µs making 1 call to import
313144µs48µsuse Moose::Meta::TypeConstraint::Parameterized;
# spent 4µs making 1 call to import
32326µs9µsuse Moose::Meta::TypeConstraint::Parameterizable;
# spent 6µs making 1 call to import
333137µs46µsuse Moose::Meta::TypeConstraint::Class;
# spent 4µs making 1 call to import
343135µs45µsuse Moose::Meta::TypeConstraint::Role;
# spent 4µs making 1 call to import
353130µs43µsuse Moose::Meta::TypeConstraint::Enum;
# spent 4µs making 1 call to import
363148µs49µsuse Moose::Meta::TypeConstraint::DuckType;
# spent 5µs making 1 call to import
37329µs10µsuse Moose::Meta::TypeCoercion;
# spent 3µs making 1 call to import
38330µs10µsuse Moose::Meta::TypeCoercion::Union;
# spent 3µs making 1 call to import
393139µs46µsuse Moose::Meta::TypeConstraint::Registry;
# spent 4µs making 1 call to import
403225µs75µsuse Moose::Util::TypeConstraints::OptimizedConstraints;
# spent 10µs making 1 call to import
41
42117µs17µsMoose::Exporter->setup_import_methods(
# spent 1.59ms making 1 call to Moose::Exporter::setup_import_methods
43 as_is => [
44 qw(
45 type subtype class_type role_type maybe_type duck_type
46 as where message optimize_as
47 coerce from via
48 enum
49 find_type_constraint
50 register_type_constraint
51 match_on_type )
52 ],
53);
54
55## --------------------------------------------------------
56## type registry and some useful functions for it
57## --------------------------------------------------------
58
5918µs8µsmy $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
# spent 452µs making 1 call to Moose::Meta::TypeConstraint::Registry::new
60
61sub get_type_constraint_registry {$REGISTRY}
62111µs11µs
# spent 18µs (13+5) within Moose::Util::TypeConstraints::list_all_type_constraints which was called # once (13µs+5µs) at line 869
sub list_all_type_constraints { keys %{ $REGISTRY->type_constraints } }
63
64sub export_type_constraints_as_functions {
65 my $pkg = caller();
6633.30ms1.10ms no strict 'refs';
# spent 27µs making 1 call to strict::unimport
67 foreach my $constraint ( keys %{ $REGISTRY->type_constraints } ) {
68 my $tc = $REGISTRY->get_type_constraint($constraint)
69 ->_compiled_type_constraint;
70 *{"${pkg}::${constraint}"}
71 = sub { $tc->( $_[0] ) ? 1 : undef }; # the undef is for compat
72 }
73}
74
75sub create_type_constraint_union {
76 my @type_constraint_names;
77
78 if ( scalar @_ == 1 && _detect_type_constraint_union( $_[0] ) ) {
79 @type_constraint_names = _parse_type_constraint_union( $_[0] );
80 }
81 else {
82 @type_constraint_names = @_;
83 }
84
85 ( scalar @type_constraint_names >= 2 )
86 || __PACKAGE__->_throw_error(
87 "You must pass in at least 2 type names to make a union");
88
89 my @type_constraints = map {
90 find_or_parse_type_constraint($_)
91 || __PACKAGE__->_throw_error(
92 "Could not locate type constraint ($_) for the union");
93 } @type_constraint_names;
94
95 return Moose::Meta::TypeConstraint::Union->new(
96 type_constraints => \@type_constraints );
97}
98
99sub create_parameterized_type_constraint {
100 my $type_constraint_name = shift;
101 my ( $base_type, $type_parameter )
102 = _parse_parameterized_type_constraint($type_constraint_name);
103
104 ( defined $base_type && defined $type_parameter )
105 || __PACKAGE__->_throw_error(
106 "Could not parse type name ($type_constraint_name) correctly");
107
108 if ( $REGISTRY->has_type_constraint($base_type) ) {
109 my $base_type_tc = $REGISTRY->get_type_constraint($base_type);
110 return _create_parameterized_type_constraint(
111 $base_type_tc,
112 $type_parameter
113 );
114 }
115 else {
116 __PACKAGE__->_throw_error(
117 "Could not locate the base type ($base_type)");
118 }
119}
120
121sub _create_parameterized_type_constraint {
122 my ( $base_type_tc, $type_parameter ) = @_;
123 if ( $base_type_tc->can('parameterize') ) {
124 return $base_type_tc->parameterize($type_parameter);
125 }
126 else {
127 return Moose::Meta::TypeConstraint::Parameterized->new(
128 name => $base_type_tc->name . '[' . $type_parameter . ']',
129 parent => $base_type_tc,
130 type_parameter =>
131 find_or_create_isa_type_constraint($type_parameter),
132 );
133 }
134}
135
136#should we also support optimized checks?
137
# spent 1.53ms (135µs+1.39) within Moose::Util::TypeConstraints::create_class_type_constraint which was called 7 times, avg 218µs/call: # 7 times (135µs+1.39ms) by Moose::Util::TypeConstraints::class_type at line 362, avg 218µs/call
sub create_class_type_constraint {
13828140µs5µs my ( $class, $options ) = @_;
139
140# too early for this check
141#find_type_constraint("ClassName")->check($class)
142# || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
143
144 my %options = (
145 class => $class,
146 name => $class,
147 %{ $options || {} },
148 );
149
150 $options{name} ||= "__ANON__";
151
152 Moose::Meta::TypeConstraint::Class->new(%options);
# spent 1.39ms making 7 calls to Moose::Meta::TypeConstraint::Class::new, avg 199µs/call
153}
154
155sub create_role_type_constraint {
156 my ( $role, $options ) = @_;
157
158# too early for this check
159#find_type_constraint("ClassName")->check($class)
160# || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
161
162 my %options = (
163 role => $role,
164 name => $role,
165 %{ $options || {} },
166 );
167
168 $options{name} ||= "__ANON__";
169
170 Moose::Meta::TypeConstraint::Role->new(%options);
171}
172
173sub find_or_create_type_constraint {
174 my ( $type_constraint_name, $options_for_anon_type ) = @_;
175
176 if ( my $constraint
177 = find_or_parse_type_constraint($type_constraint_name) ) {
178 return $constraint;
179 }
180 elsif ( defined $options_for_anon_type ) {
181
182 # NOTE:
183 # if there is no $options_for_anon_type
184 # specified, then we assume they don't
185 # want to create one, and return nothing.
186
187 # otherwise assume that we should create
188 # an ANON type with the $options_for_anon_type
189 # options which can be passed in. It should
190 # be noted that these don't get registered
191 # so we need to return it.
192 # - SL
193 return Moose::Meta::TypeConstraint->new(
194 name => '__ANON__',
195 %{$options_for_anon_type}
196 );
197 }
198
199 return;
200}
201
202
# spent 1.16ms (130µs+1.03) within Moose::Util::TypeConstraints::find_or_create_isa_type_constraint which was called 23 times, avg 50µs/call: # 17 times (83µs+692µs) by Moose::Util::TypeConstraints::_create_type_constraint at line 547, avg 46µs/call # 6 times (47µs+333µs) by Moose::Meta::Attribute::_process_options at line 291 of /usr/local/lib/perl/5.10.0/Moose/Meta/Attribute.pm, avg 63µs/call
sub find_or_create_isa_type_constraint {
2034698µs2µs my $type_constraint_name = shift;
204127µs27µs find_or_parse_type_constraint($type_constraint_name)
# spent 1.03ms making 23 calls to Moose::Util::TypeConstraints::find_or_parse_type_constraint, avg 45µs/call
205 || create_class_type_constraint($type_constraint_name);
206}
207
208sub find_or_create_does_type_constraint {
209 my $type_constraint_name = shift;
210 find_or_parse_type_constraint($type_constraint_name)
211 || create_role_type_constraint($type_constraint_name);
212}
213
214
# spent 1.03ms (195µs+830µs) within Moose::Util::TypeConstraints::find_or_parse_type_constraint which was called 23 times, avg 45µs/call: # 23 times (195µs+830µs) by Moose::Util::TypeConstraints::find_or_create_isa_type_constraint at line 204, avg 45µs/call
sub find_or_parse_type_constraint {
21569214µs3µs my $type_constraint_name = normalize_type_constraint_name(shift);
# spent 126µs making 23 calls to Moose::Util::TypeConstraints::normalize_type_constraint_name, avg 5µs/call
216 my $constraint;
217
218124µs24µs if ( $constraint = find_type_constraint($type_constraint_name) ) {
# spent 704µs making 23 calls to Moose::Util::TypeConstraints::find_type_constraint, avg 31µs/call
219 return $constraint;
220 }
221 elsif ( _detect_type_constraint_union($type_constraint_name) ) {
222 $constraint = create_type_constraint_union($type_constraint_name);
223 }
224 elsif ( _detect_parameterized_type_constraint($type_constraint_name) ) {
225 $constraint
226 = create_parameterized_type_constraint($type_constraint_name);
227 }
228 else {
229 return;
230 }
231
232 $REGISTRY->add_type_constraint($constraint);
233 return $constraint;
234}
235
236
# spent 126µs within Moose::Util::TypeConstraints::normalize_type_constraint_name which was called 23 times, avg 5µs/call: # 23 times (126µs+0s) by Moose::Util::TypeConstraints::find_or_parse_type_constraint at line 215, avg 5µs/call
sub normalize_type_constraint_name {
2376976µs1µs my $type_constraint_name = shift;
238 $type_constraint_name =~ s/\s//g;
239 return $type_constraint_name;
240}
241
242sub _confess {
243 my $error = shift;
244
245 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
246 Carp::confess($error);
247}
248
249## --------------------------------------------------------
250## exported functions ...
251## --------------------------------------------------------
252
253
# spent 1.28ms (352µs+925µs) within Moose::Util::TypeConstraints::find_type_constraint which was called 41 times, avg 31µs/call: # 23 times (186µs+517µs) by Moose::Util::TypeConstraints::find_or_parse_type_constraint at line 218, avg 31µs/call # 7 times (60µs+195µs) by Moose::Meta::TypeConstraint::Class::new at line 23 of /usr/local/lib/perl/5.10.0/Moose/Meta/TypeConstraint/Class.pm, avg 36µs/call # 7 times (73µs+136µs) by Moose::init_meta at line 162 of /usr/local/lib/perl/5.10.0/Moose.pm, avg 30µs/call # once (10µs+19µs) at line 788 # once (8µs+19µs) at line 809 # once (7µs+19µs) at line 847 # once (8µs+19µs) at line 830
sub find_type_constraint {
254157505µs3µs my $type = shift;
255
256 if ( blessed $type and $type->isa("Moose::Meta::TypeConstraint") ) {
# spent 98µs making 41 calls to Scalar::Util::blessed, avg 2µs/call
257 return $type;
258 }
259 else {
260 return unless $REGISTRY->has_type_constraint($type);
# spent 481µs making 41 calls to Moose::Meta::TypeConstraint::Registry::has_type_constraint, avg 12µs/call
261 return $REGISTRY->get_type_constraint($type);
# spent 346µs making 34 calls to Moose::Meta::TypeConstraint::Registry::get_type_constraint, avg 10µs/call
262 }
263}
264
265
# spent 333µs (75+258) within Moose::Util::TypeConstraints::register_type_constraint which was called 7 times, avg 48µs/call: # 7 times (75µs+258µs) by Moose::Util::TypeConstraints::class_type at line 362, avg 48µs/call
sub register_type_constraint {
2662888µs3µs my $constraint = shift;
267 __PACKAGE__->_throw_error("can't register an unnamed type constraint")
# spent 42µs making 7 calls to Moose::Meta::TypeConstraint::name, avg 6µs/call
268 unless defined $constraint->name;
269 $REGISTRY->add_type_constraint($constraint);
# spent 216µs making 7 calls to Moose::Meta::TypeConstraint::Registry::add_type_constraint, avg 31µs/call
270 return $constraint;
271}
272
273# type constructors
274
275
# spent 392µs (23+369) within Moose::Util::TypeConstraints::type which was called # once (23µs+369µs) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:707] at line 707
sub type {
276
277 # back-compat version, called without sugar
278656µs9µs if ( !any { ( reftype($_) || '' ) eq 'HASH' } @_ ) {
# spent 28µs making 1 call to List::MoreUtils::any # spent 7µs making 2 calls to Scalar::Util::reftype, avg 3µs/call
279 Moose::Deprecated::deprecated(
280 feature => 'type without sugar',
281 message =>
282 'Calling type() with a simple list of parameters is deprecated'
283 );
284
285 return _create_type_constraint( $_[0], undef, $_[1] );
286 }
287
288 my $name = shift;
289
290 my %p = map { %{$_} } @_;
291
292 return _create_type_constraint(
293 $name, undef, $p{where}, $p{message},
294 $p{optimize_as}
295 );
296}
297
298
# spent 4.50ms (541µs+3.96) within Moose::Util::TypeConstraints::subtype which was called 17 times, avg 264µs/call: # once (33µs+366µs) at line 708 # once (42µs+333µs) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:710] at line 710 # once (35µs+305µs) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:711] at line 711 # once (28µs+258µs) at line 733 # once (30µs+251µs) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:714] at line 714 # once (32µs+227µs) at line 717 # once (33µs+218µs) at line 723 # once (28µs+216µs) at line 738 # once (37µs+204µs) at line 735 # once (30µs+204µs) at line 720 # once (43µs+191µs) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:745] at line 745 # once (29µs+203µs) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:761] at line 761 # once (28µs+199µs) at line 727 # once (27µs+199µs) at line 756 # once (27µs+196µs) at line 730 # once (32µs+191µs) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:766] at line 766 # once (28µs+193µs) at line 752
sub subtype {
299
300 # crazy back-compat code for being called without sugar ...
301 #
302 # subtype 'Parent', sub { where };
303136521µs4µs if ( scalar @_ == 2 && ( reftype( $_[1] ) || '' ) eq 'CODE' ) {
# spent 4µs making 1 call to Scalar::Util::reftype
304 Moose::Deprecated::deprecated(
305 feature => 'subtype without sugar',
306 message =>
307 'Calling subtype() with a simple list of parameters is deprecated'
308 );
309
310 return _create_type_constraint( undef, @_ );
311 }
312
313 # subtype 'Parent', sub { where }, sub { message };
314 # subtype 'Parent', sub { where }, sub { message }, sub { optimized };
31516149µs9µs if ( scalar @_ >= 3 && all { ( reftype($_) || '' ) eq 'CODE' }
# spent 139µs making 16 calls to List::MoreUtils::all, avg 9µs/call # spent 53µs making 16 calls to Scalar::Util::reftype, avg 3µs/call
316 @_[ 1 .. $#_ ] ) {
317 Moose::Deprecated::deprecated(
318 feature => 'subtype without sugar',
319 message =>
320 'Calling subtype() with a simple list of parameters is deprecated'
321 );
322
323 return _create_type_constraint( undef, @_ );
324 }
325
326 # subtype 'Name', 'Parent', ...
32734102µs3µs if ( scalar @_ >= 2 && all { !ref } @_[ 0, 1 ] ) {
# spent 97µs making 17 calls to List::MoreUtils::all, avg 6µs/call
328 Moose::Deprecated::deprecated(
329 feature => 'subtype without sugar',
330 message =>
331 'Calling subtype() with a simple list of parameters is deprecated'
332 );
333
334 return _create_type_constraint(@_);
335 }
336
337 if ( @_ == 1 && !ref $_[0] ) {
338 __PACKAGE__->_throw_error(
339 'A subtype cannot consist solely of a name, it must have a parent'
340 );
341 }
342
343 # The blessed check is mostly to accommodate MooseX::Types, which
344 # uses an object which overloads stringification as a type name.
345 my $name = ref $_[0] && !blessed $_[0] ? undef : shift;
346
347 my %p = map { %{$_} } @_;
348
349 # subtype Str => where { ... };
350 if ( !exists $p{as} ) {
351 $p{as} = $name;
352 $name = undef;
353 }
354
355 return _create_type_constraint(
# spent 3.72ms making 17 calls to Moose::Util::TypeConstraints::_create_type_constraint, avg 219µs/call
356 $name, $p{as}, $p{where}, $p{message},
357 $p{optimize_as}
358 );
359}
360
361
# spent 1.91ms (53µs+1.86) within Moose::Util::TypeConstraints::class_type which was called 7 times, avg 273µs/call: # 7 times (53µs+1.86ms) by Moose::init_meta at line 162 of /usr/local/lib/perl/5.10.0/Moose.pm, avg 273µs/call
sub class_type {
362782µs12µs register_type_constraint(
# spent 1.53ms making 7 calls to Moose::Util::TypeConstraints::create_class_type_constraint, avg 218µs/call # spent 333µs making 7 calls to Moose::Util::TypeConstraints::register_type_constraint, avg 48µs/call
363 create_class_type_constraint(
364 $_[0],
365 ( defined( $_[1] ) ? $_[1] : () ),
366 )
367 );
368}
369
370sub role_type ($;$) {
371 register_type_constraint(
372 create_role_type_constraint(
373 $_[0],
374 ( defined( $_[1] ) ? $_[1] : () ),
375 )
376 );
377}
378
379sub maybe_type {
380 my ($type_parameter) = @_;
381
382 register_type_constraint(
383 $REGISTRY->get_type_constraint('Maybe')->parameterize($type_parameter)
384 );
385}
386
387sub duck_type {
388 my ( $type_name, @methods ) = @_;
389 if ( ref $type_name eq 'ARRAY' && !@methods ) {
390 @methods = @$type_name;
391 $type_name = undef;
392 }
393 if ( @methods == 1 && ref $methods[0] eq 'ARRAY' ) {
394 @methods = @{ $methods[0] };
395 }
396
397 register_type_constraint(
398 create_duck_type_constraint(
399 $type_name,
400 \@methods,
401 )
402 );
403}
404
405sub coerce {
406 my ( $type_name, @coercion_map ) = @_;
407 _install_type_coercions( $type_name, \@coercion_map );
408}
409
410# The trick of returning @_ lets us avoid having to specify a
411# prototype. Perl will parse this:
412#
413# subtype 'Foo'
414# => as 'Str'
415# => where { ... }
416#
417# as this:
418#
419# subtype( 'Foo', as( 'Str', where { ... } ) );
420#
421# If as() returns all it's extra arguments, this just works, and
422# preserves backwards compatibility.
4231740µs2µs
# spent 93µs within Moose::Util::TypeConstraints::as which was called 17 times, avg 5µs/call: # once (9µs+0s) at line 708 # once (6µs+0s) at line 752 # once (6µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:745] at line 745 # once (6µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:761] at line 761 # once (6µs+0s) at line 727 # once (5µs+0s) at line 735 # once (5µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:710] at line 710 # once (5µs+0s) at line 720 # once (5µs+0s) at line 738 # once (5µs+0s) at line 717 # once (5µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:711] at line 711 # once (5µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:714] at line 714 # once (5µs+0s) at line 723 # once (5µs+0s) at line 756 # once (5µs+0s) at line 730 # once (5µs+0s) at line 733 # once (5µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:766] at line 766
sub as { { as => shift }, @_ }
4241726µs2µs
# spent 93µs within Moose::Util::TypeConstraints::where which was called 17 times, avg 5µs/call: # once (10µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:707] at line 707 # once (6µs+0s) at line 735 # once (6µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:761] at line 761 # once (6µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:710] at line 710 # once (6µs+0s) at line 727 # once (5µs+0s) at line 730 # once (5µs+0s) at line 723 # once (5µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:745] at line 745 # once (5µs+0s) at line 720 # once (5µs+0s) at line 738 # once (5µs+0s) at line 752 # once (5µs+0s) at line 756 # once (5µs+0s) at line 733 # once (5µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:714] at line 714 # once (5µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:766] at line 766 # once (5µs+0s) at line 717 # once (5µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:711] at line 711
sub where (&) { { where => $_[0] } }
425sub message (&) { { message => $_[0] } }
4261319µs1µs
# spent 58µs within Moose::Util::TypeConstraints::optimize_as which was called 13 times, avg 4µs/call: # once (7µs+0s) at line 717 # once (5µs+0s) at line 738 # once (5µs+0s) at line 735 # once (4µs+0s) at line 720 # once (4µs+0s) at line 727 # once (4µs+0s) at line 730 # once (4µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:761] at line 761 # once (4µs+0s) at line 723 # once (4µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:745] at line 745 # once (4µs+0s) by Moose::Util::TypeConstraints::__ANON__[/usr/local/lib/perl/5.10.0/Moose/Util/TypeConstraints.pm:766] at line 766 # once (4µs+0s) at line 733 # once (4µs+0s) at line 756 # once (4µs+0s) at line 752
sub optimize_as (&) { { optimize_as => $_[0] } }
427
428sub from {@_}
429sub via (&) { $_[0] }
430
431sub enum {
432 my ( $type_name, @values ) = @_;
433
434 # NOTE:
435 # if only an array-ref is passed then
436 # you get an anon-enum
437 # - SL
438 if ( ref $type_name eq 'ARRAY' ) {
439 @values == 0
440 || __PACKAGE__->_throw_error("enum called with an array reference and additional arguments. Did you mean to parenthesize the enum call's parameters?");
441
442 @values = @$type_name;
443 $type_name = undef;
444 }
445 if ( @values == 1 && ref $values[0] eq 'ARRAY' ) {
446 @values = @{ $values[0] };
447 }
448
449 register_type_constraint(
450 create_enum_type_constraint(
451 $type_name,
452 \@values,
453 )
454 );
455}
456
457sub create_enum_type_constraint {
458 my ( $type_name, $values ) = @_;
459
460 Moose::Meta::TypeConstraint::Enum->new(
461 name => $type_name || '__ANON__',
462 values => $values,
463 );
464}
465
466sub create_duck_type_constraint {
467 my ( $type_name, $methods ) = @_;
468
469 Moose::Meta::TypeConstraint::DuckType->new(
470 name => $type_name || '__ANON__',
471 methods => $methods,
472 );
473}
474
475sub match_on_type {
476 my ($to_match, @cases) = @_;
477 my $default;
478 if (@cases % 2 != 0) {
479 $default = pop @cases;
480 (ref $default eq 'CODE')
481 || __PACKAGE__->_throw_error("Default case must be a CODE ref, not $default");
482 }
483 while (@cases) {
484 my ($type, $action) = splice @cases, 0, 2;
485
486 unless (blessed $type && $type->isa('Moose::Meta::TypeConstraint')) {
487 $type = find_or_parse_type_constraint($type)
488 || __PACKAGE__->_throw_error("Cannot find or parse the type '$type'")
489 }
490
491 (ref $action eq 'CODE')
492 || __PACKAGE__->_throw_error("Match action must be a CODE ref, not $action");
493
494 if ($type->check($to_match)) {
495 local $_ = $to_match;
496 return $action->($to_match);
497 }
498 }
499 (defined $default)
500 || __PACKAGE__->_throw_error("No cases matched for $to_match");
501 {
502 local $_ = $to_match;
503 return $default->($to_match);
504 }
505}
506
507
508## --------------------------------------------------------
509## desugaring functions ...
510## --------------------------------------------------------
511
512
# spent 4.06ms (499µs+3.56) within Moose::Util::TypeConstraints::_create_type_constraint which was called 18 times, avg 225µs/call: # 17 times (461µs+3.25ms) by Moose::Util::TypeConstraints::subtype at line 355, avg 219µs/call # once (38µs+302µs) by Moose::Util::TypeConstraints::type at line 292
sub _create_type_constraint ($$$;$$) {
513271583µs2µs my $name = shift;
514 my $parent = shift;
515 my $check = shift;
516 my $message = shift;
517 my $optimized = shift;
518
519 my $pkg_defined_in = scalar( caller(1) );
520
521 if ( defined $name ) {
522 my $type = $REGISTRY->get_type_constraint($name);
# spent 191µs making 18 calls to Moose::Meta::TypeConstraint::Registry::get_type_constraint, avg 11µs/call
523
524 ( $type->_package_defined_in eq $pkg_defined_in )
525 || _confess(
526 "The type constraint '$name' has already been created in "
527 . $type->_package_defined_in
528 . " and cannot be created again in "
529 . $pkg_defined_in )
530 if defined $type;
531
532 $name =~ /^[\w:\.]+$/
533 or die qq{$name contains invalid characters for a type name.}
534 . qq{ Names can contain alphanumeric character, ":", and "."\n};
535 }
536
537 my %opts = (
538 name => $name,
539 package_defined_in => $pkg_defined_in,
540
541 ( $check ? ( constraint => $check ) : () ),
542 ( $message ? ( message => $message ) : () ),
543 ( $optimized ? ( optimized => $optimized ) : () ),
544 );
545
546 my $constraint;
547176µs76µs if (
# spent 1.80ms making 17 calls to Moose::Meta::TypeConstraint::create_child_type, avg 106µs/call # spent 775µs making 17 calls to Moose::Util::TypeConstraints::find_or_create_isa_type_constraint, avg 46µs/call # spent 49µs making 17 calls to Scalar::Util::blessed, avg 3µs/call
548 defined $parent
549 and $parent
550 = blessed $parent
551 ? $parent
552 : find_or_create_isa_type_constraint($parent)
553 ) {
554 $constraint = $parent->create_child_type(%opts);
555 }
556 else {
557 $constraint = Moose::Meta::TypeConstraint->new(%opts);
# spent 236µs making 1 call to Moose::Meta::TypeConstraint::new
558 }
559
560 $REGISTRY->add_type_constraint($constraint)
# spent 512µs making 18 calls to Moose::Meta::TypeConstraint::Registry::add_type_constraint, avg 28µs/call
561 if defined $name;
562
563 return $constraint;
564}
565
566sub _install_type_coercions ($$) {
567 my ( $type_name, $coercion_map ) = @_;
568 my $type = find_type_constraint($type_name);
569 ( defined $type )
570 || __PACKAGE__->_throw_error(
571 "Cannot find type '$type_name', perhaps you forgot to load it");
572 if ( $type->has_coercion ) {
573 $type->coercion->add_type_coercions(@$coercion_map);
574 }
575 else {
576 my $type_coercion = Moose::Meta::TypeCoercion->new(
577 type_coercion_map => $coercion_map,
578 type_constraint => $type
579 );
580 $type->coercion($type_coercion);
581 }
582}
583
584## --------------------------------------------------------
585## type notation parsing ...
586## --------------------------------------------------------
587
588{
589
590 # All I have to say is mugwump++ cause I know
591 # do not even have enough regexp-fu to be able
592 # to have written this (I can only barely
593 # understand it as it is)
594 # - SL
595
5964411µs103µs use re "eval";
# spent 25µs making 1 call to re::import
597
59818µs8µs my $valid_chars = qr{[\w:\.]};
599122µs22µs my $type_atom = qr{ (?>$valid_chars+) }x;
60011µs1µs my $ws = qr{ (?>\s*) }x;
601114µs14µs my $op_union = qr{ $ws \| $ws }x;
602
6031600ns600ns my ($type, $type_capture_parts, $type_with_parameter, $union, $any);
60416µs6µs if (Class::MOP::IS_RUNNING_ON_5_10) {
6051700ns700ns my $type_pattern
606 = q{ (?&type_atom) (?: \[ (?&ws) (?&any) (?&ws) \] )? };
6071500ns500ns my $type_capture_parts_pattern
608 = q{ ((?&type_atom)) (?: \[ (?&ws) ((?&any)) (?&ws) \] )? };
6091500ns500ns my $type_with_parameter_pattern
610 = q{ (?&type_atom) \[ (?&ws) (?&any) (?&ws) \] };
6111500ns500ns my $union_pattern
612 = q{ (?&type) (?> (?: (?&op_union) (?&type) )+ ) };
6131400ns400ns my $any_pattern
614 = q{ (?&type) | (?&union) };
615
6161100µs100µs my $defines = qr{(?(DEFINE)
617 (?<valid_chars> $valid_chars)
618 (?<type_atom> $type_atom)
619 (?<ws> $ws)
620 (?<op_union> $op_union)
621 (?<type> $type_pattern)
622 (?<type_capture_parts> $type_capture_parts_pattern)
623 (?<type_with_parameter> $type_with_parameter_pattern)
624 (?<union> $union_pattern)
625 (?<any> $any_pattern)
626 )}x;
627
628183µs83µs $type = qr{ $type_pattern $defines }x;
629173µs73µs $type_capture_parts = qr{ $type_capture_parts_pattern $defines }x;
630174µs74µs $type_with_parameter = qr{ $type_with_parameter_pattern $defines }x;
631167µs67µs $union = qr{ $union_pattern $defines }x;
632189µs89µs $any = qr{ $any_pattern $defines }x;
633 }
634 else {
635 $type
636 = qr{ $type_atom (?: \[ $ws (??{$any}) $ws \] )? }x;
637 $type_capture_parts
638 = qr{ ($type_atom) (?: \[ $ws ((??{$any})) $ws \] )? }x;
639 $type_with_parameter
640 = qr{ $type_atom \[ $ws (??{$any}) $ws \] }x;
641 $union
642 = qr{ $type (?> (?: $op_union $type )+ ) }x;
643 $any
644 = qr{ $type | $union }x;
645 }
646
647
648 sub _parse_parameterized_type_constraint {
649380µs27µs { no warnings 'void'; $any; } # force capture of interpolated lexical
# spent 24µs making 1 call to warnings::unimport
650 $_[0] =~ m{ $type_capture_parts }x;
651 return ( $1, $2 );
652 }
653
654 sub _detect_parameterized_type_constraint {
655363µs21µs { no warnings 'void'; $any; } # force capture of interpolated lexical
# spent 25µs making 1 call to warnings::unimport
656 $_[0] =~ m{ ^ $type_with_parameter $ }x;
657 }
658
659 sub _parse_type_constraint_union {
6603129µs43µs { no warnings 'void'; $any; } # force capture of interpolated lexical
# spent 19µs making 1 call to warnings::unimport
661 my $given = shift;
662 my @rv;
663 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
664 push @rv => $1;
665 }
666 ( pos($given) eq length($given) )
667 || __PACKAGE__->_throw_error( "'$given' didn't parse (parse-pos="
668 . pos($given)
669 . " and str-length="
670 . length($given)
671 . ")" );
672 @rv;
673 }
674
675 sub _detect_type_constraint_union {
67631.88ms628µs { no warnings 'void'; $any; } # force capture of interpolated lexical
# spent 24µs making 1 call to warnings::unimport
677 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
678 }
679}
680
681## --------------------------------------------------------
682# define some basic built-in types
683## --------------------------------------------------------
684
685# By making these classes immutable before creating all the types we
686# below, we avoid repeatedly calling the slow MOP-based accessors.
687$_->make_immutable(
688932µs4µs inline_constructor => 1,
# spent 24µs making 9 calls to Class::MOP::Class::is_mutable, avg 3µs/call
689 constructor_name => "_new",
690
691 # these are Class::MOP accessors, so they need inlining
692 inline_accessors => 1
6931090µs9µs ) for grep { $_->is_mutable }
# spent 34.5ms making 9 calls to Class::MOP::Class::make_immutable, avg 3.83ms/call # spent 95µs making 9 calls to Class::MOP::class_of, avg 11µs/call
694 map { Class::MOP::class_of($_) }
695 qw(
696 Moose::Meta::TypeConstraint
697 Moose::Meta::TypeConstraint::Union
698 Moose::Meta::TypeConstraint::Parameterized
699 Moose::Meta::TypeConstraint::Parameterizable
700 Moose::Meta::TypeConstraint::Class
701 Moose::Meta::TypeConstraint::Role
702 Moose::Meta::TypeConstraint::Enum
703 Moose::Meta::TypeConstraint::DuckType
704 Moose::Meta::TypeConstraint::Registry
7051100ns100ns);
706
707121µs21µstype 'Any' => where {1}; # meta-type including all
# spent 392µs making 1 call to Moose::Util::TypeConstraints::type # spent 10µs making 1 call to Moose::Util::TypeConstraints::where
708114µs14µssubtype 'Item' => as 'Any'; # base-type
# spent 399µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 9µs making 1 call to Moose::Util::TypeConstraints::as
709
710117µs17µssubtype 'Undef' => as 'Item' => where { !defined($_) };
# spent 376µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 6µs making 1 call to Moose::Util::TypeConstraints::where # spent 5µs making 1 call to Moose::Util::TypeConstraints::as
711120µs20µssubtype 'Defined' => as 'Item' => where { defined($_) };
# spent 340µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::where
712
713subtype 'Bool' => as 'Item' =>
714125µs25µs where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
# spent 281µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::where
715
716subtype 'Value' => as 'Defined' => where { !ref($_) } =>
717127µs27µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
# spent 259µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 7µs making 1 call to Moose::Util::TypeConstraints::optimize_as # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::where
718
719subtype 'Ref' => as 'Defined' => where { ref($_) } =>
720130µs30µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
# spent 234µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::where # spent 4µs making 1 call to Moose::Util::TypeConstraints::optimize_as
721
722subtype 'Str' => as 'Value' => where { ref(\$_) eq 'SCALAR' } =>
723134µs34µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
# spent 250µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 5µs making 1 call to Moose::Util::TypeConstraints::where # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 4µs making 1 call to Moose::Util::TypeConstraints::optimize_as
724
725subtype 'Num' => as 'Str' =>
726 where { Scalar::Util::looks_like_number($_) } =>
727123µs23µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
# spent 227µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 6µs making 1 call to Moose::Util::TypeConstraints::where # spent 6µs making 1 call to Moose::Util::TypeConstraints::as # spent 4µs making 1 call to Moose::Util::TypeConstraints::optimize_as
728
729subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } =>
730127µs27µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
# spent 223µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 5µs making 1 call to Moose::Util::TypeConstraints::where # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 4µs making 1 call to Moose::Util::TypeConstraints::optimize_as
731
732subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
733132µs32µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
# spent 286µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::where # spent 4µs making 1 call to Moose::Util::TypeConstraints::optimize_as
734subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } =>
735131µs31µs optimize_as
# spent 240µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 6µs making 1 call to Moose::Util::TypeConstraints::where # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::optimize_as
736 \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
737subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
738129µs29µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
# spent 244µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::optimize_as # spent 5µs making 1 call to Moose::Util::TypeConstraints::where
739
740# NOTE:
741# scalar filehandles are GLOB refs,
742# but a GLOB ref is not always a filehandle
743subtype 'FileHandle' => as 'GlobRef' => where {
744 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
745127µs27µs} => optimize_as
# spent 234µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 6µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::where # spent 4µs making 1 call to Moose::Util::TypeConstraints::optimize_as
746 \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
747
748# NOTE:
749# blessed(qr/.../) returns true,.. how odd
750subtype 'Object' => as 'Ref' =>
751 where { blessed($_) && blessed($_) ne 'Regexp' } =>
752126µs26µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
# spent 221µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 6µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::where # spent 4µs making 1 call to Moose::Util::TypeConstraints::optimize_as
753
754# This type is deprecated.
755subtype 'Role' => as 'Object' => where { $_->can('does') } =>
756122µs22µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
# spent 227µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::where # spent 4µs making 1 call to Moose::Util::TypeConstraints::optimize_as
757
75814µs4µsmy $_class_name_checker = sub { };
759
760subtype 'ClassName' => as 'Str' =>
761129µs29µs where { Class::MOP::is_class_loaded($_) } => optimize_as
# spent 232µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 6µs making 1 call to Moose::Util::TypeConstraints::where # spent 6µs making 1 call to Moose::Util::TypeConstraints::as # spent 4µs making 1 call to Moose::Util::TypeConstraints::optimize_as
762 \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
763
764subtype 'RoleName' => as 'ClassName' => where {
765 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
766123µs23µs} => optimize_as
# spent 223µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 5µs making 1 call to Moose::Util::TypeConstraints::as # spent 5µs making 1 call to Moose::Util::TypeConstraints::where # spent 4µs making 1 call to Moose::Util::TypeConstraints::optimize_as
767 \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
768
769## --------------------------------------------------------
770# parameterizable types ...
771
772$REGISTRY->add_type_constraint(
773 Moose::Meta::TypeConstraint::Parameterizable->new(
774 name => 'ScalarRef',
775 package_defined_in => __PACKAGE__,
776 parent => find_type_constraint('Ref'),
777 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
778 optimized =>
779 \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef,
780 constraint_generator => sub {
781 my $type_parameter = shift;
782 my $check = $type_parameter->_compiled_type_constraint;
783 return sub {
784 return $check->(${ $_ });
785 };
786 }
787 )
788141µs41µs);
# spent 254µs making 1 call to Moose::Meta::TypeConstraint::new # spent 45µs making 1 call to Moose::Meta::TypeConstraint::Registry::add_type_constraint # spent 29µs making 1 call to Moose::Util::TypeConstraints::find_type_constraint
789
790$REGISTRY->add_type_constraint(
791 Moose::Meta::TypeConstraint::Parameterizable->new(
792 name => 'ArrayRef',
793 package_defined_in => __PACKAGE__,
794 parent => find_type_constraint('Ref'),
795 constraint => sub { ref($_) eq 'ARRAY' },
796 optimized =>
797 \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
798 constraint_generator => sub {
799 my $type_parameter = shift;
800 my $check = $type_parameter->_compiled_type_constraint;
801 return sub {
802 foreach my $x (@$_) {
803 ( $check->($x) ) || return;
804 }
805 1;
806 }
807 }
808 )
809132µs32µs);
# spent 88µs making 1 call to Moose::Meta::TypeConstraint::new # spent 28µs making 1 call to Moose::Meta::TypeConstraint::Registry::add_type_constraint # spent 28µs making 1 call to Moose::Util::TypeConstraints::find_type_constraint
810
811$REGISTRY->add_type_constraint(
812 Moose::Meta::TypeConstraint::Parameterizable->new(
813 name => 'HashRef',
814 package_defined_in => __PACKAGE__,
815 parent => find_type_constraint('Ref'),
816 constraint => sub { ref($_) eq 'HASH' },
817 optimized =>
818 \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
819 constraint_generator => sub {
820 my $type_parameter = shift;
821 my $check = $type_parameter->_compiled_type_constraint;
822 return sub {
823 foreach my $x ( values %$_ ) {
824 ( $check->($x) ) || return;
825 }
826 1;
827 }
828 }
829 )
830130µs30µs);
# spent 80µs making 1 call to Moose::Meta::TypeConstraint::new # spent 28µs making 1 call to Moose::Meta::TypeConstraint::Registry::add_type_constraint # spent 27µs making 1 call to Moose::Util::TypeConstraints::find_type_constraint
831
832$REGISTRY->add_type_constraint(
833 Moose::Meta::TypeConstraint::Parameterizable->new(
834 name => 'Maybe',
835 package_defined_in => __PACKAGE__,
836 parent => find_type_constraint('Item'),
837 constraint => sub {1},
838 constraint_generator => sub {
839 my $type_parameter = shift;
840 my $check = $type_parameter->_compiled_type_constraint;
841 return sub {
842 return 1 if not( defined($_) ) || $check->($_);
843 return;
844 }
845 }
846 )
847129µs29µs);
# spent 213µs making 1 call to Moose::Meta::TypeConstraint::new # spent 28µs making 1 call to Moose::Meta::TypeConstraint::Registry::add_type_constraint # spent 27µs making 1 call to Moose::Util::TypeConstraints::find_type_constraint
848
849my @PARAMETERIZABLE_TYPES
850528µs6µs = map { $REGISTRY->get_type_constraint($_) } qw[ScalarRef ArrayRef HashRef Maybe];
# spent 45µs making 4 calls to Moose::Meta::TypeConstraint::Registry::get_type_constraint, avg 11µs/call
851
852sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
853
854sub add_parameterizable_type {
855 my $type = shift;
856 ( blessed $type
857 && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
858 || __PACKAGE__->_throw_error(
859 "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
860 );
861 push @PARAMETERIZABLE_TYPES => $type;
862}
863
864## --------------------------------------------------------
865# end of built-in types ...
866## --------------------------------------------------------
867
868{
869217µs9µs my @BUILTINS = list_all_type_constraints();
870 sub list_all_builtin_type_constraints {@BUILTINS}
871}
872
873sub _throw_error {
874 shift;
875 require Moose;
876 unshift @_, 'Moose';
877 goto &Moose::throw_error;
878}
879
8801132µs132µs1;
881
882__END__
883
884=pod
885
886=head1 NAME
887
888Moose::Util::TypeConstraints - Type constraint system for Moose
889
890=head1 SYNOPSIS
891
892 use Moose::Util::TypeConstraints;
893
894 subtype 'Natural'
895 => as 'Int'
896 => where { $_ > 0 };
897
898 subtype 'NaturalLessThanTen'
899 => as 'Natural'
900 => where { $_ < 10 }
901 => message { "This number ($_) is not less than ten!" };
902
903 coerce 'Num'
904 => from 'Str'
905 => via { 0+$_ };
906
907 enum 'RGBColors' => qw(red green blue);
908
909 no Moose::Util::TypeConstraints;
910
911=head1 DESCRIPTION
912
913This module provides Moose with the ability to create custom type
914constraints to be used in attribute definition.
915
916=head2 Important Caveat
917
918This is B<NOT> a type system for Perl 5. These are type constraints,
919and they are not used by Moose unless you tell it to. No type
920inference is performed, expressions are not typed, etc. etc. etc.
921
922A type constraint is at heart a small "check if a value is valid"
923function. A constraint can be associated with an attribute. This
924simplifies parameter validation, and makes your code clearer to read,
925because you can refer to constraints by name.
926
927=head2 Slightly Less Important Caveat
928
929It is B<always> a good idea to quote your type names.
930
931This prevents Perl from trying to execute the call as an indirect
932object call. This can be an issue when you have a subtype with the
933same name as a valid class.
934
935For instance:
936
937 subtype DateTime => as Object => where { $_->isa('DateTime') };
938
939will I<just work>, while this:
940
941 use DateTime;
942 subtype DateTime => as Object => where { $_->isa('DateTime') };
943
944will fail silently and cause many headaches. The simple way to solve
945this, as well as future proof your subtypes from classes which have
946yet to have been created, is to quote the type name:
947
948 use DateTime;
949 subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
950
951=head2 Default Type Constraints
952
953This module also provides a simple hierarchy for Perl 5 types, here is
954that hierarchy represented visually.
955
956 Any
957 Item
958 Bool
959 Maybe[`a]
960 Undef
961 Defined
962 Value
963 Str
964 Num
965 Int
966 ClassName
967 RoleName
968 Ref
969 ScalarRef[`a]
970 ArrayRef[`a]
971 HashRef[`a]
972 CodeRef
973 RegexpRef
974 GlobRef
975 FileHandle
976 Object
977
978B<NOTE:> Any type followed by a type parameter C<[`a]> can be
979parameterized, this means you can say:
980
981 ArrayRef[Int] # an array of integers
982 HashRef[CodeRef] # a hash of str to CODE ref mappings
983 ScalarRef[Int] # a reference to an integer
984 Maybe[Str] # value may be a string, may be undefined
985
986If Moose finds a name in brackets that it does not recognize as an
987existing type, it assumes that this is a class name, for example
988C<ArrayRef[DateTime]>.
989
990B<NOTE:> Unless you parameterize a type, then it is invalid to include
991the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
992name, I<not> as a parameterization of C<ArrayRef>.
993
994B<NOTE:> The C<Undef> type constraint for the most part works
995correctly now, but edge cases may still exist, please use it
996sparingly.
997
998B<NOTE:> The C<ClassName> type constraint does a complex package
999existence check. This means that your class B<must> be loaded for this
1000type constraint to pass.
1001
1002B<NOTE:> The C<RoleName> constraint checks a string is a I<package
1003name> which is a role, like C<'MyApp::Role::Comparable'>.
1004
1005=head2 Type Constraint Naming
1006
1007Type name declared via this module can only contain alphanumeric
1008characters, colons (:), and periods (.).
1009
1010Since the types created by this module are global, it is suggested
1011that you namespace your types just as you would namespace your
1012modules. So instead of creating a I<Color> type for your
1013B<My::Graphics> module, you would call the type
1014I<My::Graphics::Types::Color> instead.
1015
1016=head2 Use with Other Constraint Modules
1017
1018This module can play nicely with other constraint modules with some
1019slight tweaking. The C<where> clause in types is expected to be a
1020C<CODE> reference which checks it's first argument and returns a
1021boolean. Since most constraint modules work in a similar way, it
1022should be simple to adapt them to work with Moose.
1023
1024For instance, this is how you could use it with
1025L<Declare::Constraints::Simple> to declare a completely new type.
1026
1027 type 'HashOfArrayOfObjects',
1028 {
1029 where => IsHashRef(
1030 -keys => HasLength,
1031 -values => IsArrayRef(IsObject)
1032 )
1033 };
1034
1035For more examples see the F<t/200_examples/004_example_w_DCS.t> test
1036file.
1037
1038Here is an example of using L<Test::Deep> and it's non-test
1039related C<eq_deeply> function.
1040
1041 type 'ArrayOfHashOfBarsAndRandomNumbers'
1042 => where {
1043 eq_deeply($_,
1044 array_each(subhashof({
1045 bar => isa('Bar'),
1046 random_number => ignore()
1047 })))
1048 };
1049
1050For a complete example see the
1051F<t/200_examples/005_example_w_TestDeep.t> test file.
1052
1053=head1 FUNCTIONS
1054
1055=head2 Type Constraint Constructors
1056
1057The following functions are used to create type constraints. They
1058will also register the type constraints your create in a global
1059registry that is used to look types up by name.
1060
1061See the L</SYNOPSIS> for an example of how to use these.
1062
1063=over 4
1064
1065=item B<< subtype 'Name' => as 'Parent' => where { } ... >>
1066
1067This creates a named subtype.
1068
1069If you provide a parent that Moose does not recognize, it will
1070automatically create a new class type constraint for this name.
1071
1072When creating a named type, the C<subtype> function should either be
1073called with the sugar helpers (C<where>, C<message>, etc), or with a
1074name and a hashref of parameters:
1075
1076 subtype( 'Foo', { where => ..., message => ... } );
1077
1078The valid hashref keys are C<as> (the parent), C<where>, C<message>,
1079and C<optimize_as>.
1080
1081=item B<< subtype as 'Parent' => where { } ... >>
1082
1083This creates an unnamed subtype and will return the type
1084constraint meta-object, which will be an instance of
1085L<Moose::Meta::TypeConstraint>.
1086
1087When creating an anonymous type, the C<subtype> function should either
1088be called with the sugar helpers (C<where>, C<message>, etc), or with
1089just a hashref of parameters:
1090
1091 subtype( { where => ..., message => ... } );
1092
1093=item B<class_type ($class, ?$options)>
1094
1095Creates a new subtype of C<Object> with the name C<$class> and the
1096metaclass L<Moose::Meta::TypeConstraint::Class>.
1097
1098=item B<role_type ($role, ?$options)>
1099
1100Creates a C<Role> type constraint with the name C<$role> and the
1101metaclass L<Moose::Meta::TypeConstraint::Role>.
1102
1103=item B<maybe_type ($type)>
1104
1105Creates a type constraint for either C<undef> or something of the
1106given type.
1107
1108=item B<duck_type ($name, \@methods)>
1109
1110This will create a subtype of Object and test to make sure the value
1111C<can()> do the methods in C<\@methods>.
1112
1113This is intended as an easy way to accept non-Moose objects that
1114provide a certain interface. If you're using Moose classes, we
1115recommend that you use a C<requires>-only Role instead.
1116
1117=item B<duck_type (\@methods)>
1118
1119If passed an ARRAY reference as the only parameter instead of the
1120C<$name>, C<\@methods> pair, this will create an unnamed duck type.
1121This can be used in an attribute definition like so:
1122
1123 has 'cache' => (
1124 is => 'ro',
1125 isa => duck_type( [qw( get_set )] ),
1126 );
1127
1128=item B<enum ($name, \@values)>
1129
1130This will create a basic subtype for a given set of strings.
1131The resulting constraint will be a subtype of C<Str> and
1132will match any of the items in C<\@values>. It is case sensitive.
1133See the L</SYNOPSIS> for a simple example.
1134
1135B<NOTE:> This is not a true proper enum type, it is simply
1136a convenient constraint builder.
1137
1138=item B<enum (\@values)>
1139
1140If passed an ARRAY reference as the only parameter instead of the
1141C<$name>, C<\@values> pair, this will create an unnamed enum. This
1142can then be used in an attribute definition like so:
1143
1144 has 'sort_order' => (
1145 is => 'ro',
1146 isa => enum([qw[ ascending descending ]]),
1147 );
1148
1149=item B<as 'Parent'>
1150
1151This is just sugar for the type constraint construction syntax.
1152
1153It takes a single argument, which is the name of a parent type.
1154
1155=item B<where { ... }>
1156
1157This is just sugar for the type constraint construction syntax.
1158
1159It takes a subroutine reference as an argument. When the type
1160constraint is tested, the reference is run with the value to be tested
1161in C<$_>. This reference should return true or false to indicate
1162whether or not the constraint check passed.
1163
1164=item B<message { ... }>
1165
1166This is just sugar for the type constraint construction syntax.
1167
1168It takes a subroutine reference as an argument. When the type
1169constraint fails, then the code block is run with the value provided
1170in C<$_>. This reference should return a string, which will be used in
1171the text of the exception thrown.
1172
1173=item B<optimize_as { ... }>
1174
1175This can be used to define a "hand optimized" version of your
1176type constraint which can be used to avoid traversing a subtype
1177constraint hierarchy.
1178
1179B<NOTE:> You should only use this if you know what you are doing,
1180all the built in types use this, so your subtypes (assuming they
1181are shallow) will not likely need to use this.
1182
1183=item B<< type 'Name' => where { } ... >>
1184
1185This creates a base type, which has no parent.
1186
1187The C<type> function should either be called with the sugar helpers
1188(C<where>, C<message>, etc), or with a name and a hashref of
1189parameters:
1190
1191 type( 'Foo', { where => ..., message => ... } );
1192
1193The valid hashref keys are C<where>, C<message>, and C<optimize_as>.
1194
1195=back
1196
1197=head2 Type Constraint Utilities
1198
1199=over 4
1200
1201=item B<< match_on_type $value => ( $type => \&action, ... ?\&default ) >>
1202
1203This is a utility function for doing simple type based dispatching similar to
1204match/case in OCaml and case/of in Haskell. It is not as featureful as those
1205languages, nor does not it support any kind of automatic destructuring
1206bind. Here is a simple Perl pretty printer dispatching over the core Moose
1207types.
1208
1209 sub ppprint {
1210 my $x = shift;
1211 match_on_type $x => (
1212 HashRef => sub {
1213 my $hash = shift;
1214 '{ '
1215 . (
1216 join ", " => map { $_ . ' => ' . ppprint( $hash->{$_} ) }
1217 sort keys %$hash
1218 ) . ' }';
1219 },
1220 ArrayRef => sub {
1221 my $array = shift;
1222 '[ ' . ( join ", " => map { ppprint($_) } @$array ) . ' ]';
1223 },
1224 CodeRef => sub {'sub { ... }'},
1225 RegexpRef => sub { 'qr/' . $_ . '/' },
1226 GlobRef => sub { '*' . B::svref_2object($_)->NAME },
1227 Object => sub { $_->can('to_string') ? $_->to_string : $_ },
1228 ScalarRef => sub { '\\' . ppprint( ${$_} ) },
1229 Num => sub {$_},
1230 Str => sub { '"' . $_ . '"' },
1231 Undef => sub {'undef'},
1232 => sub { die "I don't know what $_ is" }
1233 );
1234 }
1235
1236Or a simple JSON serializer:
1237
1238 sub to_json {
1239 my $x = shift;
1240 match_on_type $x => (
1241 HashRef => sub {
1242 my $hash = shift;
1243 '{ '
1244 . (
1245 join ", " =>
1246 map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
1247 sort keys %$hash
1248 ) . ' }';
1249 },
1250 ArrayRef => sub {
1251 my $array = shift;
1252 '[ ' . ( join ", " => map { to_json($_) } @$array ) . ' ]';
1253 },
1254 Num => sub {$_},
1255 Str => sub { '"' . $_ . '"' },
1256 Undef => sub {'null'},
1257 => sub { die "$_ is not acceptable json type" }
1258 );
1259 }
1260
1261The matcher is done by mapping a C<$type> to an C<\&action>. The C<$type> can
1262be either a string type or a L<Moose::Meta::TypeConstraint> object, and
1263C<\&action> is a subroutine reference. This function will dispatch on the
1264first match for C<$value>. It is possible to have a catch-all by providing an
1265additional subroutine reference as the final argument to C<match_on_type>.
1266
1267=back
1268
1269=head2 Type Coercion Constructors
1270
1271You can define coercions for type constraints, which allow you to
1272automatically transform values to something valid for the type
1273constraint. If you ask your accessor to coerce, then Moose will run
1274the type-coercion code first, followed by the type constraint
1275check. This feature should be used carefully as it is very powerful
1276and could easily take off a limb if you are not careful.
1277
1278See the L</SYNOPSIS> for an example of how to use these.
1279
1280=over 4
1281
1282=item B<< coerce 'Name' => from 'OtherName' => via { ... } >>
1283
1284This defines a coercion from one type to another. The C<Name> argument
1285is the type you are coercing I<to>.
1286
1287=item B<from 'OtherName'>
1288
1289This is just sugar for the type coercion construction syntax.
1290
1291It takes a single type name (or type object), which is the type being
1292coerced I<from>.
1293
1294=item B<via { ... }>
1295
1296This is just sugar for the type coercion construction syntax.
1297
1298It takes a subroutine reference. This reference will be called with
1299the value to be coerced in C<$_>. It is expected to return a new value
1300of the proper type for the coercion.
1301
1302=back
1303
1304=head2 Creating and Finding Type Constraints
1305
1306These are additional functions for creating and finding type
1307constraints. Most of these functions are not available for
1308importing. The ones that are importable as specified.
1309
1310=over 4
1311
1312=item B<find_type_constraint($type_name)>
1313
1314This function can be used to locate the L<Moose::Meta::TypeConstraint>
1315object for a named type.
1316
1317This function is importable.
1318
1319=item B<register_type_constraint($type_object)>
1320
1321This function will register a L<Moose::Meta::TypeConstraint> with the
1322global type registry.
1323
1324This function is importable.
1325
1326=item B<normalize_type_constraint_name($type_constraint_name)>
1327
1328This method takes a type constraint name and returns the normalized
1329form. This removes any whitespace in the string.
1330
1331=item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
1332
1333This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1334or a list of names. It returns a new
1335L<Moose::Meta::TypeConstraint::Union> object.
1336
1337=item B<create_parameterized_type_constraint($type_name)>
1338
1339Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1340this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1341object. The C<BaseType> must exist already exist as a parameterizable
1342type.
1343
1344=item B<create_class_type_constraint($class, $options)>
1345
1346Given a class name this function will create a new
1347L<Moose::Meta::TypeConstraint::Class> object for that class name.
1348
1349The C<$options> is a hash reference that will be passed to the
1350L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
1351
1352=item B<create_role_type_constraint($role, $options)>
1353
1354Given a role name this function will create a new
1355L<Moose::Meta::TypeConstraint::Role> object for that role name.
1356
1357The C<$options> is a hash reference that will be passed to the
1358L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
1359
1360=item B<create_enum_type_constraint($name, $values)>
1361
1362Given a enum name this function will create a new
1363L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1364
1365=item B<create_duck_type_constraint($name, $methods)>
1366
1367Given a duck type name this function will create a new
1368L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
1369
1370=item B<find_or_parse_type_constraint($type_name)>
1371
1372Given a type name, this first attempts to find a matching constraint
1373in the global registry.
1374
1375If the type name is a union or parameterized type, it will create a
1376new object of the appropriate, but if given a "regular" type that does
1377not yet exist, it simply returns false.
1378
1379When given a union or parameterized type, the member or base type must
1380already exist.
1381
1382If it creates a new union or parameterized type, it will add it to the
1383global registry.
1384
1385=item B<find_or_create_isa_type_constraint($type_name)>
1386
1387=item B<find_or_create_does_type_constraint($type_name)>
1388
1389These functions will first call C<find_or_parse_type_constraint>. If
1390that function does not return a type, a new anonymous type object will
1391be created.
1392
1393The C<isa> variant will use C<create_class_type_constraint> and the
1394C<does> variant will use C<create_role_type_constraint>.
1395
1396=item B<get_type_constraint_registry>
1397
1398Returns the L<Moose::Meta::TypeConstraint::Registry> object which
1399keeps track of all type constraints.
1400
1401=item B<list_all_type_constraints>
1402
1403This will return a list of type constraint names in the global
1404registry. You can then fetch the actual type object using
1405C<find_type_constraint($type_name)>.
1406
1407=item B<list_all_builtin_type_constraints>
1408
1409This will return a list of builtin type constraints, meaning those
1410which are defined in this module. See the L<Default Type Constraints>
1411section for a complete list.
1412
1413=item B<export_type_constraints_as_functions>
1414
1415This will export all the current type constraints as functions into
1416the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1417mostly used for testing, but it might prove useful to others.
1418
1419=item B<get_all_parameterizable_types>
1420
1421This returns all the parameterizable types that have been registered,
1422as a list of type objects.
1423
1424=item B<add_parameterizable_type($type)>
1425
1426Adds C<$type> to the list of parameterizable types
1427
1428=back
1429
1430=head1 BUGS
1431
1432See L<Moose/BUGS> for details on reporting bugs.
1433
1434=head1 AUTHOR
1435
1436Stevan Little E<lt>stevan@iinteractive.comE<gt>
1437
1438=head1 COPYRIGHT AND LICENSE
1439
1440Copyright 2006-2010 by Infinity Interactive, Inc.
1441
1442L<http://www.iinteractive.com>
1443
1444This library is free software; you can redistribute it and/or modify
1445it under the same terms as Perl itself.
1446
1447=cut