← Index
NYTProf Performance Profile   « block view • line view • sub view »
For 01.HTTP.t
  Run on Tue May 4 15:25:55 2010
Reported on Tue May 4 15:26:05 2010

File /usr/local/lib/perl5/site_perl/5.10.1/darwin-2level/Moose/Util/TypeConstraints.pm
Statements Executed 883
Statement Execution Time 8.89ms
Subroutines — ordered by exclusive time
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
1111.24ms2.40msMoose::Util::TypeConstraints::::BEGIN@29Moose::Util::TypeConstraints::BEGIN@29
1111.24ms1.80msMoose::Util::TypeConstraints::::BEGIN@32Moose::Util::TypeConstraints::BEGIN@32
1111.09ms1.62msMoose::Util::TypeConstraints::::BEGIN@33Moose::Util::TypeConstraints::BEGIN@33
111813µs860µsMoose::Util::TypeConstraints::::BEGIN@572Moose::Util::TypeConstraints::BEGIN@572
111628µs1.35msMoose::Util::TypeConstraints::::BEGIN@35Moose::Util::TypeConstraints::BEGIN@35
111507µs585µsMoose::Util::TypeConstraints::::BEGIN@39Moose::Util::TypeConstraints::BEGIN@39
111463µs929µsMoose::Util::TypeConstraints::::BEGIN@34Moose::Util::TypeConstraints::BEGIN@34
111449µs2.25msMoose::Util::TypeConstraints::::BEGIN@30Moose::Util::TypeConstraints::BEGIN@30
111436µs1.54msMoose::Util::TypeConstraints::::BEGIN@38Moose::Util::TypeConstraints::BEGIN@38
1821412µs2.94msMoose::Util::TypeConstraints::::_create_type_constraintMoose::Util::TypeConstraints::_create_type_constraint
17171360µs3.17msMoose::Util::TypeConstraints::::subtypeMoose::Util::TypeConstraints::subtype
772230µs230µsMoose::Util::TypeConstraints::::CORE:regcompMoose::Util::TypeConstraints::CORE:regcomp (opcode)
2373161µs391µsMoose::Util::TypeConstraints::::find_type_constraintMoose::Util::TypeConstraints::find_type_constraint
1711127µs552µsMoose::Util::TypeConstraints::::find_or_parse_type_constraintMoose::Util::TypeConstraints::find_or_parse_type_constraint
171189µs707µsMoose::Util::TypeConstraints::::find_or_create_isa_type_constraintMoose::Util::TypeConstraints::find_or_create_isa_type_constraint
171155µs67µsMoose::Util::TypeConstraints::::normalize_type_constraint_nameMoose::Util::TypeConstraints::normalize_type_constraint_name
181240µs40µsMoose::Util::TypeConstraints::::CORE:matchMoose::Util::TypeConstraints::CORE:match (opcode)
1717134µs34µsMoose::Util::TypeConstraints::::asMoose::Util::TypeConstraints::as
1717128µs28µsMoose::Util::TypeConstraints::::whereMoose::Util::TypeConstraints::where
11121µs282µsMoose::Util::TypeConstraints::::typeMoose::Util::TypeConstraints::type
1313116µs16µsMoose::Util::TypeConstraints::::optimize_asMoose::Util::TypeConstraints::optimize_as
11115µs47µsMoose::Util::TypeConstraints::::register_type_constraintMoose::Util::TypeConstraints::register_type_constraint
99214µs14µsMoose::Util::TypeConstraints::::CORE:qrMoose::Util::TypeConstraints::CORE:qr (opcode)
11114µs44µsMoose::Util::TypeConstraints::::BEGIN@5Moose::Util::TypeConstraints::BEGIN@5
11114µs236µsMoose::Util::TypeConstraints::::create_class_type_constraintMoose::Util::TypeConstraints::create_class_type_constraint
11114µs24µsMoose::Util::TypeConstraints::::BEGIN@619Moose::Util::TypeConstraints::BEGIN@619
171212µs12µsMoose::Util::TypeConstraints::::CORE:substMoose::Util::TypeConstraints::CORE:subst (opcode)
11112µs13µsMoose::Util::TypeConstraints::::list_all_type_constraintsMoose::Util::TypeConstraints::list_all_type_constraints
11112µs12µsMoose::Util::TypeConstraints::::BEGIN@4Moose::Util::TypeConstraints::BEGIN@4
11110µs293µsMoose::Util::TypeConstraints::::class_typeMoose::Util::TypeConstraints::class_type
11110µs19µsMoose::Util::TypeConstraints::::BEGIN@598Moose::Util::TypeConstraints::BEGIN@598
11110µs25µsMoose::Util::TypeConstraints::::BEGIN@592Moose::Util::TypeConstraints::BEGIN@592
1117µs25µsMoose::Util::TypeConstraints::::BEGIN@65Moose::Util::TypeConstraints::BEGIN@65
1117µs15µsMoose::Util::TypeConstraints::::BEGIN@603Moose::Util::TypeConstraints::BEGIN@603
1117µs26µsMoose::Util::TypeConstraints::::BEGIN@7Moose::Util::TypeConstraints::BEGIN@7
1117µs7µsMoose::Util::TypeConstraints::::BEGIN@36Moose::Util::TypeConstraints::BEGIN@36
1116µs32µsMoose::Util::TypeConstraints::::BEGIN@6Moose::Util::TypeConstraints::BEGIN@6
1114µs4µsMoose::Util::TypeConstraints::::BEGIN@28Moose::Util::TypeConstraints::BEGIN@28
1114µs4µsMoose::Util::TypeConstraints::::BEGIN@31Moose::Util::TypeConstraints::BEGIN@31
1113µs3µsMoose::Util::TypeConstraints::::BEGIN@37Moose::Util::TypeConstraints::BEGIN@37
0000s0sMoose::Util::TypeConstraints::::__ANON__[:277]Moose::Util::TypeConstraints::__ANON__[:277]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:302]Moose::Util::TypeConstraints::__ANON__[:302]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:308]Moose::Util::TypeConstraints::__ANON__[:308]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:650]Moose::Util::TypeConstraints::__ANON__[:650]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:653]Moose::Util::TypeConstraints::__ANON__[:653]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:654]Moose::Util::TypeConstraints::__ANON__[:654]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:657]Moose::Util::TypeConstraints::__ANON__[:657]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:659]Moose::Util::TypeConstraints::__ANON__[:659]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:662]Moose::Util::TypeConstraints::__ANON__[:662]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:665]Moose::Util::TypeConstraints::__ANON__[:665]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:669]Moose::Util::TypeConstraints::__ANON__[:669]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:672]Moose::Util::TypeConstraints::__ANON__[:672]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:675]Moose::Util::TypeConstraints::__ANON__[:675]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:677]Moose::Util::TypeConstraints::__ANON__[:677]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:680]Moose::Util::TypeConstraints::__ANON__[:680]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:688]Moose::Util::TypeConstraints::__ANON__[:688]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:694]Moose::Util::TypeConstraints::__ANON__[:694]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:698]Moose::Util::TypeConstraints::__ANON__[:698]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:701]Moose::Util::TypeConstraints::__ANON__[:701]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:704]Moose::Util::TypeConstraints::__ANON__[:704]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:709]Moose::Util::TypeConstraints::__ANON__[:709]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:70]Moose::Util::TypeConstraints::__ANON__[:70]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:720]Moose::Util::TypeConstraints::__ANON__[:720]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:728]Moose::Util::TypeConstraints::__ANON__[:728]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:729]Moose::Util::TypeConstraints::__ANON__[:729]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:738]Moose::Util::TypeConstraints::__ANON__[:738]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:749]Moose::Util::TypeConstraints::__ANON__[:749]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:750]Moose::Util::TypeConstraints::__ANON__[:750]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:759]Moose::Util::TypeConstraints::__ANON__[:759]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:770]Moose::Util::TypeConstraints::__ANON__[:770]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:771]Moose::Util::TypeConstraints::__ANON__[:771]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:780]Moose::Util::TypeConstraints::__ANON__[:780]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:787]Moose::Util::TypeConstraints::__ANON__[:787]
0000s0sMoose::Util::TypeConstraints::::__ANON__[:788]Moose::Util::TypeConstraints::__ANON__[:788]
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
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1
2package Moose::Util::TypeConstraints;
3
4329µs112µs
# spent 12µs within Moose::Util::TypeConstraints::BEGIN@4 which was called # once (12µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 4
use Carp ();
# spent 12µs making 1 call to Moose::Util::TypeConstraints::BEGIN@4
5325µs274µs
# spent 44µs (14+30) within Moose::Util::TypeConstraints::BEGIN@5 which was called # once (14µs+30µs) by Moose::Meta::Attribute::BEGIN@18 at line 5
use List::MoreUtils qw( all any );
# spent 44µs making 1 call to Moose::Util::TypeConstraints::BEGIN@5 # spent 30µs making 1 call to Exporter::import
6321µs258µs
# spent 32µs (6+26) within Moose::Util::TypeConstraints::BEGIN@6 which was called # once (6µs+26µs) by Moose::Meta::Attribute::BEGIN@18 at line 6
use Scalar::Util qw( blessed reftype );
# spent 32µs making 1 call to Moose::Util::TypeConstraints::BEGIN@6 # spent 26µs making 1 call to Exporter::import
7361µs244µs
# spent 26µs (7+19) within Moose::Util::TypeConstraints::BEGIN@7 which was called # once (7µs+19µs) by Moose::Meta::Attribute::BEGIN@18 at line 7
use Moose::Exporter;
# spent 26µs making 1 call to Moose::Util::TypeConstraints::BEGIN@7 # spent 19µs making 1 call to Moose::Exporter::import
8
91900nsour $VERSION = '0.98';
10115µs$VERSION = eval $VERSION;
111400nsour $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
28318µs14µs
# spent 4µs within Moose::Util::TypeConstraints::BEGIN@28 which was called # once (4µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 28
use Moose::Meta::TypeConstraint;
# spent 4µs making 1 call to Moose::Util::TypeConstraints::BEGIN@28
293672µs12.40ms
# spent 2.40ms (1.24+1.16) within Moose::Util::TypeConstraints::BEGIN@29 which was called # once (1.24ms+1.16ms) by Moose::Meta::Attribute::BEGIN@18 at line 29
use Moose::Meta::TypeConstraint::Union;
# spent 2.40ms making 1 call to Moose::Util::TypeConstraints::BEGIN@29
30395µs12.25ms
# spent 2.25ms (449µs+1.80) within Moose::Util::TypeConstraints::BEGIN@30 which was called # once (449µs+1.80ms) by Moose::Meta::Attribute::BEGIN@18 at line 30
use Moose::Meta::TypeConstraint::Parameterized;
# spent 2.25ms making 1 call to Moose::Util::TypeConstraints::BEGIN@30
31318µs14µs
# spent 4µs within Moose::Util::TypeConstraints::BEGIN@31 which was called # once (4µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 31
use Moose::Meta::TypeConstraint::Parameterizable;
# spent 4µs making 1 call to Moose::Util::TypeConstraints::BEGIN@31
323686µs11.80ms
# spent 1.80ms (1.24+562µs) within Moose::Util::TypeConstraints::BEGIN@32 which was called # once (1.24ms+562µs) by Moose::Meta::Attribute::BEGIN@18 at line 32
use Moose::Meta::TypeConstraint::Class;
# spent 1.80ms making 1 call to Moose::Util::TypeConstraints::BEGIN@32
333640µs11.62ms
# spent 1.62ms (1.09+532µs) within Moose::Util::TypeConstraints::BEGIN@33 which was called # once (1.09ms+532µs) by Moose::Meta::Attribute::BEGIN@18 at line 33
use Moose::Meta::TypeConstraint::Role;
# spent 1.62ms making 1 call to Moose::Util::TypeConstraints::BEGIN@33
34397µs1929µs
# spent 929µs (463+466) within Moose::Util::TypeConstraints::BEGIN@34 which was called # once (463µs+466µs) by Moose::Meta::Attribute::BEGIN@18 at line 34
use Moose::Meta::TypeConstraint::Enum;
# spent 929µs making 1 call to Moose::Util::TypeConstraints::BEGIN@34
35396µs11.35ms
# spent 1.35ms (628µs+718µs) within Moose::Util::TypeConstraints::BEGIN@35 which was called # once (628µs+718µs) by Moose::Meta::Attribute::BEGIN@18 at line 35
use Moose::Meta::TypeConstraint::DuckType;
# spent 1.35ms making 1 call to Moose::Util::TypeConstraints::BEGIN@35
36321µs17µs
# spent 7µs within Moose::Util::TypeConstraints::BEGIN@36 which was called # once (7µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 36
use Moose::Meta::TypeCoercion;
# spent 7µs making 1 call to Moose::Util::TypeConstraints::BEGIN@36
37317µs13µs
# spent 3µs within Moose::Util::TypeConstraints::BEGIN@37 which was called # once (3µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 37
use Moose::Meta::TypeCoercion::Union;
# spent 3µs making 1 call to Moose::Util::TypeConstraints::BEGIN@37
38397µs11.54ms
# spent 1.54ms (436µs+1.10) within Moose::Util::TypeConstraints::BEGIN@38 which was called # once (436µs+1.10ms) by Moose::Meta::Attribute::BEGIN@18 at line 38
use Moose::Meta::TypeConstraint::Registry;
# spent 1.54ms making 1 call to Moose::Util::TypeConstraints::BEGIN@38
393170µs1585µs
# spent 585µs (507+78) within Moose::Util::TypeConstraints::BEGIN@39 which was called # once (507µs+78µs) by Moose::Meta::Attribute::BEGIN@18 at line 39
use Moose::Util::TypeConstraints::OptimizedConstraints;
# spent 585µs making 1 call to Moose::Util::TypeConstraints::BEGIN@39
40
4117µs1877µsMoose::Exporter->setup_import_methods(
# spent 877µs making 1 call to Moose::Exporter::setup_import_methods
42 as_is => [
43 qw(
44 type subtype class_type role_type maybe_type duck_type
45 as where message optimize_as
46 coerce from via
47 enum
48 find_type_constraint
49 register_type_constraint
50 match_on_type )
51 ],
52);
53
54## --------------------------------------------------------
55## type registry and some useful functions for it
56## --------------------------------------------------------
57
5812µs1323µsmy $REGISTRY = Moose::Meta::TypeConstraint::Registry->new;
# spent 323µs making 1 call to Moose::Meta::TypeConstraint::Registry::new
59
60sub get_type_constraint_registry {$REGISTRY}
61112µs11µs
# spent 13µs (12+1000ns) within Moose::Util::TypeConstraints::list_all_type_constraints which was called # once (12µs+1000ns) by Moose::Meta::Attribute::BEGIN@18 at line 812
sub list_all_type_constraints { keys %{ $REGISTRY->type_constraints } }
62
63sub export_type_constraints_as_functions {
64 my $pkg = caller();
6532.37ms243µs
# spent 25µs (7+18) within Moose::Util::TypeConstraints::BEGIN@65 which was called # once (7µs+18µs) by Moose::Meta::Attribute::BEGIN@18 at line 65
no strict 'refs';
# spent 25µs making 1 call to Moose::Util::TypeConstraints::BEGIN@65 # spent 18µs making 1 call to strict::unimport
66 foreach my $constraint ( keys %{ $REGISTRY->type_constraints } ) {
67 my $tc = $REGISTRY->get_type_constraint($constraint)
68 ->_compiled_type_constraint;
69 *{"${pkg}::${constraint}"}
70 = sub { $tc->( $_[0] ) ? 1 : undef }; # the undef is for compat
71 }
72}
73
74sub create_type_constraint_union {
75 my @type_constraint_names;
76
77 if ( scalar @_ == 1 && _detect_type_constraint_union( $_[0] ) ) {
78 @type_constraint_names = _parse_type_constraint_union( $_[0] );
79 }
80 else {
81 @type_constraint_names = @_;
82 }
83
84 ( scalar @type_constraint_names >= 2 )
85 || __PACKAGE__->_throw_error(
86 "You must pass in at least 2 type names to make a union");
87
88 my @type_constraints = map {
89 find_or_parse_type_constraint($_)
90 || __PACKAGE__->_throw_error(
91 "Could not locate type constraint ($_) for the union");
92 } @type_constraint_names;
93
94 return Moose::Meta::TypeConstraint::Union->new(
95 type_constraints => \@type_constraints );
96}
97
98sub create_parameterized_type_constraint {
99 my $type_constraint_name = shift;
100 my ( $base_type, $type_parameter )
101 = _parse_parameterized_type_constraint($type_constraint_name);
102
103 ( defined $base_type && defined $type_parameter )
104 || __PACKAGE__->_throw_error(
105 "Could not parse type name ($type_constraint_name) correctly");
106
107 if ( $REGISTRY->has_type_constraint($base_type) ) {
108 my $base_type_tc = $REGISTRY->get_type_constraint($base_type);
109 return _create_parameterized_type_constraint(
110 $base_type_tc,
111 $type_parameter
112 );
113 }
114 else {
115 __PACKAGE__->_throw_error(
116 "Could not locate the base type ($base_type)");
117 }
118}
119
120sub _create_parameterized_type_constraint {
121 my ( $base_type_tc, $type_parameter ) = @_;
122 if ( $base_type_tc->can('parameterize') ) {
123 return $base_type_tc->parameterize($type_parameter);
124 }
125 else {
126 return Moose::Meta::TypeConstraint::Parameterized->new(
127 name => $base_type_tc->name . '[' . $type_parameter . ']',
128 parent => $base_type_tc,
129 type_parameter =>
130 find_or_create_isa_type_constraint($type_parameter),
131 );
132 }
133}
134
135#should we also support optimized checks?
136
# spent 236µs (14+222) within Moose::Util::TypeConstraints::create_class_type_constraint which was called # once (14µs+222µs) by Moose::Util::TypeConstraints::class_type at line 337
sub create_class_type_constraint {
137415µs my ( $class, $options ) = @_;
138
139# too early for this check
140#find_type_constraint("ClassName")->check($class)
141# || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
142
143 my %options = (
144 class => $class,
145 name => $class,
146 %{ $options || {} },
147 );
148
149 $options{name} ||= "__ANON__";
150
151 Moose::Meta::TypeConstraint::Class->new(%options);
# spent 222µs making 1 call to Moose::Meta::TypeConstraint::Class::new
152}
153
154sub create_role_type_constraint {
155 my ( $role, $options ) = @_;
156
157# too early for this check
158#find_type_constraint("ClassName")->check($class)
159# || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
160
161 my %options = (
162 role => $role,
163 name => $role,
164 %{ $options || {} },
165 );
166
167 $options{name} ||= "__ANON__";
168
169 Moose::Meta::TypeConstraint::Role->new(%options);
170}
171
172sub find_or_create_type_constraint {
173 my ( $type_constraint_name, $options_for_anon_type ) = @_;
174
175 if ( my $constraint
176 = find_or_parse_type_constraint($type_constraint_name) ) {
177 return $constraint;
178 }
179 elsif ( defined $options_for_anon_type ) {
180
181 # NOTE:
182 # if there is no $options_for_anon_type
183 # specified, then we assume they don't
184 # want to create one, and return nothing.
185
186 # otherwise assume that we should create
187 # an ANON type with the $options_for_anon_type
188 # options which can be passed in. It should
189 # be noted that these don't get registered
190 # so we need to return it.
191 # - SL
192 return Moose::Meta::TypeConstraint->new(
193 name => '__ANON__',
194 %{$options_for_anon_type}
195 );
196 }
197
198 return;
199}
200
201
# spent 707µs (89+618) within Moose::Util::TypeConstraints::find_or_create_isa_type_constraint which was called 17 times, avg 42µs/call: # 17 times (89µs+618µs) by Moose::Util::TypeConstraints::_create_type_constraint at line 523, avg 42µs/call
sub find_or_create_isa_type_constraint {
2023434µs my $type_constraint_name = shift;
203128µs34618µs find_or_parse_type_constraint($type_constraint_name)
# spent 552µs making 17 calls to Moose::Util::TypeConstraints::find_or_parse_type_constraint, avg 32µs/call # spent 66µs making 17 calls to Moose::Meta::TypeConstraint::__ANON__[Moose/Meta/TypeConstraint.pm:8], avg 4µs/call
204 || create_class_type_constraint($type_constraint_name);
205}
206
207sub find_or_create_does_type_constraint {
208 my $type_constraint_name = shift;
209 find_or_parse_type_constraint($type_constraint_name)
210 || create_role_type_constraint($type_constraint_name);
211}
212
213
# spent 552µs (127+425) within Moose::Util::TypeConstraints::find_or_parse_type_constraint which was called 17 times, avg 32µs/call: # 17 times (127µs+425µs) by Moose::Util::TypeConstraints::find_or_create_isa_type_constraint at line 203, avg 32µs/call
sub find_or_parse_type_constraint {
2145158µs1767µs my $type_constraint_name = normalize_type_constraint_name(shift);
# spent 67µs making 17 calls to Moose::Util::TypeConstraints::normalize_type_constraint_name, avg 4µs/call
215 my $constraint;
216
217133µs34358µs if ( $constraint = find_type_constraint($type_constraint_name) ) {
# spent 279µs making 17 calls to Moose::Util::TypeConstraints::find_type_constraint, avg 16µs/call # spent 79µs making 17 calls to Moose::Meta::TypeConstraint::__ANON__[Moose/Meta/TypeConstraint.pm:8], avg 5µs/call
218 return $constraint;
219 }
220 elsif ( _detect_type_constraint_union($type_constraint_name) ) {
221 $constraint = create_type_constraint_union($type_constraint_name);
222 }
223 elsif ( _detect_parameterized_type_constraint($type_constraint_name) ) {
224 $constraint
225 = create_parameterized_type_constraint($type_constraint_name);
226 }
227 else {
228 return;
229 }
230
231 $REGISTRY->add_type_constraint($constraint);
232 return $constraint;
233}
234
235
# spent 67µs (55+12) within Moose::Util::TypeConstraints::normalize_type_constraint_name which was called 17 times, avg 4µs/call: # 17 times (55µs+12µs) by Moose::Util::TypeConstraints::find_or_parse_type_constraint at line 214, avg 4µs/call
sub normalize_type_constraint_name {
2365177µs my $type_constraint_name = shift;
237 $type_constraint_name =~ s/\s//g;
# spent 12µs making 17 calls to Moose::Util::TypeConstraints::CORE:subst, avg 718ns/call
238 return $type_constraint_name;
239}
240
241sub _confess {
242 my $error = shift;
243
244 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
245 Carp::confess($error);
246}
247
248## --------------------------------------------------------
249## exported functions ...
250## --------------------------------------------------------
251
252
# spent 391µs (161+230) within Moose::Util::TypeConstraints::find_type_constraint which was called 23 times, avg 17µs/call: # 17 times (113µs+166µs) by Moose::Util::TypeConstraints::find_or_parse_type_constraint at line 217, avg 16µs/call # once (11µs+14µs) by Moose::init_meta at line 155 of Moose.pm # once (8µs+14µs) by Moose::Meta::TypeConstraint::Class::new at line 23 of Moose/Meta/TypeConstraint/Class.pm # once (7µs+9µs) by Moose::Meta::Attribute::BEGIN@18 at line 731 # once (7µs+9µs) by Moose::Meta::Attribute::BEGIN@18 at line 752 # once (7µs+9µs) by Moose::Meta::Attribute::BEGIN@18 at line 790 # once (7µs+9µs) by Moose::Meta::Attribute::BEGIN@18 at line 773
sub find_type_constraint {
25391145µs my $type = shift;
254
255 if ( blessed $type and $type->isa("Moose::Meta::TypeConstraint") ) {
# spent 8µs making 23 calls to Scalar::Util::blessed, avg 348ns/call
256 return $type;
257 }
258 else {
259 return unless $REGISTRY->has_type_constraint($type);
# spent 125µs making 23 calls to Moose::Meta::TypeConstraint::Registry::has_type_constraint, avg 5µs/call
260 return $REGISTRY->get_type_constraint($type);
# spent 97µs making 22 calls to Moose::Meta::TypeConstraint::Registry::get_type_constraint, avg 4µs/call
261 }
262}
263
264
# spent 47µs (15+32) within Moose::Util::TypeConstraints::register_type_constraint which was called # once (15µs+32µs) by Moose::Util::TypeConstraints::class_type at line 337
sub register_type_constraint {
265411µs my $constraint = shift;
266 __PACKAGE__->_throw_error("can't register an unnamed type constraint")
# spent 3µs making 1 call to Moose::Meta::TypeConstraint::name
267 unless defined $constraint->name;
268 $REGISTRY->add_type_constraint($constraint);
269 return $constraint;
270}
271
272# type constructors
273
274
# spent 282µs (21+260) within Moose::Util::TypeConstraints::type which was called # once (21µs+260µs) by Moose::Meta::Attribute::BEGIN@18 at line 650
sub type {
275
276 # back-compat version, called without sugar
277656µs334µs if ( !any { ( reftype($_) || '' ) eq 'HASH' } @_ ) {
# spent 32µs making 1 call to List::MoreUtils::any # spent 2µs making 2 calls to Scalar::Util::reftype, avg 1µs/call
278 return _create_type_constraint( $_[0], undef, $_[1] );
279 }
280
281 my $name = shift;
282
283 my %p = map { %{$_} } @_;
284
285 return _create_type_constraint(
286 $name, undef, $p{where}, $p{message},
287 $p{optimize_as}
288 );
289}
290
291
# spent 3.17ms (360µs+2.81) within Moose::Util::TypeConstraints::subtype which was called 17 times, avg 186µs/call: # once (35µs+251µs) by Moose::Meta::Attribute::BEGIN@18 at line 651 # once (21µs+213µs) by Moose::Meta::Attribute::BEGIN@18 at line 654 # once (24µs+199µs) by Moose::Meta::Attribute::BEGIN@18 at line 653 # once (21µs+199µs) by Moose::Meta::Attribute::BEGIN@18 at line 657 # once (31µs+178µs) by Moose::Meta::Attribute::BEGIN@18 at line 660 # once (21µs+155µs) by Moose::Meta::Attribute::BEGIN@18 at line 666 # once (21µs+154µs) by Moose::Meta::Attribute::BEGIN@18 at line 663 # once (19µs+155µs) by Moose::Meta::Attribute::BEGIN@18 at line 676 # once (19µs+150µs) by Moose::Meta::Attribute::BEGIN@18 at line 695 # once (20µs+148µs) by Moose::Meta::Attribute::BEGIN@18 at line 678 # once (19µs+148µs) by Moose::Meta::Attribute::BEGIN@18 at line 704 # once (18µs+148µs) by Moose::Meta::Attribute::BEGIN@18 at line 681 # once (19µs+142µs) by Moose::Meta::Attribute::BEGIN@18 at line 699 # once (19µs+142µs) by Moose::Meta::Attribute::BEGIN@18 at line 688 # once (19µs+142µs) by Moose::Meta::Attribute::BEGIN@18 at line 670 # once (19µs+141µs) by Moose::Meta::Attribute::BEGIN@18 at line 709 # once (19µs+140µs) by Moose::Meta::Attribute::BEGIN@18 at line 673
sub subtype {
292
293 # crazy back-compat code for being called without sugar ...
294 #
295 # subtype 'Parent', sub { where };
296136298µs1700ns if ( scalar @_ == 2 && ( reftype( $_[1] ) || '' ) eq 'CODE' ) {
# spent 700ns making 1 call to Scalar::Util::reftype
297 return _create_type_constraint( undef, @_ );
298 }
299
300 # subtype 'Parent', sub { where }, sub { message };
301 # subtype 'Parent', sub { where }, sub { message }, sub { optimized };
3021691µs3275µs if ( scalar @_ >= 3 && all { ( reftype($_) || '' ) eq 'CODE' }
# spent 64µs making 16 calls to List::MoreUtils::all, avg 4µs/call # spent 11µs making 16 calls to Scalar::Util::reftype, avg 681ns/call
303 @_[ 1 .. $#_ ] ) {
304 return _create_type_constraint( undef, @_ );
305 }
306
307 # subtype 'Name', 'Parent', ...
3083455µs1728µs if ( scalar @_ >= 2 && all { !ref } @_[ 0, 1 ] ) {
# spent 28µs making 17 calls to List::MoreUtils::all, avg 2µs/call
309 return _create_type_constraint(@_);
310 }
311
312 if ( @_ == 1 && !ref $_[0] ) {
313 __PACKAGE__->_throw_error(
314 'A subtype cannot consist solely of a name, it must have a parent'
315 );
316 }
317
318 # The blessed check is mostly to accommodate MooseX::Types, which
319 # uses an object which overloads stringification as a type name.
320 my $name = ref $_[0] && !blessed $_[0] ? undef : shift;
321
322 my %p = map { %{$_} } @_;
323
324 # subtype Str => where { ... };
325 if ( !exists $p{as} ) {
326 $p{as} = $name;
327 $name = undef;
328 }
329
330 return _create_type_constraint(
# spent 2.71ms making 17 calls to Moose::Util::TypeConstraints::_create_type_constraint, avg 160µs/call
331 $name, $p{as}, $p{where}, $p{message},
332 $p{optimize_as}
333 );
334}
335
336
# spent 293µs (10+283) within Moose::Util::TypeConstraints::class_type which was called # once (10µs+283µs) by Moose::init_meta at line 155 of Moose.pm
sub class_type {
33718µs2283µs register_type_constraint(
338 create_class_type_constraint(
339 $_[0],
340 ( defined( $_[1] ) ? $_[1] : () ),
341 )
342 );
343}
344
345sub role_type ($;$) {
346 register_type_constraint(
347 create_role_type_constraint(
348 $_[0],
349 ( defined( $_[1] ) ? $_[1] : () ),
350 )
351 );
352}
353
354sub maybe_type {
355 my ($type_parameter) = @_;
356
357 register_type_constraint(
358 $REGISTRY->get_type_constraint('Maybe')->parameterize($type_parameter)
359 );
360}
361
362sub duck_type {
363 my ( $type_name, @methods ) = @_;
364 if ( ref $type_name eq 'ARRAY' && !@methods ) {
365 @methods = @$type_name;
366 $type_name = undef;
367 }
368 if ( @methods == 1 && ref $methods[0] eq 'ARRAY' ) {
369 @methods = @{ $methods[0] };
370 }
371
372 register_type_constraint(
373 create_duck_type_constraint(
374 $type_name,
375 \@methods,
376 )
377 );
378}
379
380sub coerce {
381 my ( $type_name, @coercion_map ) = @_;
382 _install_type_coercions( $type_name, \@coercion_map );
383}
384
385# The trick of returning @_ lets us avoid having to specify a
386# prototype. Perl will parse this:
387#
388# subtype 'Foo'
389# => as 'Str'
390# => where { ... }
391#
392# as this:
393#
394# subtype( 'Foo', as( 'Str', where { ... } ) );
395#
396# If as() returns all it's extra arguments, this just works, and
397# preserves backwards compatibility.
3981752µs
# spent 34µs within Moose::Util::TypeConstraints::as which was called 17 times, avg 2µs/call: # once (4µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 651 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 654 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 657 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 660 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 695 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 670 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 663 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 653 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 699 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 688 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 709 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 704 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 681 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 666 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 678 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 673 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 676
sub as { { as => shift }, @_ }
3991762µs
# spent 28µs within Moose::Util::TypeConstraints::where which was called 17 times, avg 2µs/call: # once (3µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 650 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 660 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 670 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 654 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 663 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 653 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 657 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 666 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 673 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 695 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 709 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 676 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 681 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 688 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 699 # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 678 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 704
sub where (&) { { where => $_[0] } }
400sub message (&) { { message => $_[0] } }
4011331µs
# spent 16µs within Moose::Util::TypeConstraints::optimize_as which was called 13 times, avg 1µs/call: # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 660 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 676 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 704 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 666 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 678 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 663 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 709 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 673 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 695 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 681 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 688 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 699 # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 670
sub optimize_as (&) { { optimize_as => $_[0] } }
402
403sub from {@_}
404sub via (&) { $_[0] }
405
406sub enum {
407 my ( $type_name, @values ) = @_;
408
409 # NOTE:
410 # if only an array-ref is passed then
411 # you get an anon-enum
412 # - SL
413 if ( ref $type_name eq 'ARRAY' && !@values ) {
414 @values = @$type_name;
415 $type_name = undef;
416 }
417 if ( @values == 1 && ref $values[0] eq 'ARRAY' ) {
418 @values = @{ $values[0] };
419 }
420 ( scalar @values >= 2 )
421 || __PACKAGE__->_throw_error(
422 "You must have at least two values to enumerate through");
423 my %valid = map { $_ => 1 } @values;
424
425 register_type_constraint(
426 create_enum_type_constraint(
427 $type_name,
428 \@values,
429 )
430 );
431}
432
433sub create_enum_type_constraint {
434 my ( $type_name, $values ) = @_;
435
436 Moose::Meta::TypeConstraint::Enum->new(
437 name => $type_name || '__ANON__',
438 values => $values,
439 );
440}
441
442sub create_duck_type_constraint {
443 my ( $type_name, $methods ) = @_;
444
445 Moose::Meta::TypeConstraint::DuckType->new(
446 name => $type_name || '__ANON__',
447 methods => $methods,
448 );
449}
450
451sub match_on_type {
452 my ($to_match, @cases) = @_;
453 my $default;
454 if (@cases % 2 != 0) {
455 $default = pop @cases;
456 (ref $default eq 'CODE')
457 || __PACKAGE__->_throw_error("Default case must be a CODE ref, not $default");
458 }
459 while (@cases) {
460 my ($type, $action) = splice @cases, 0, 2;
461
462 unless (blessed $type && $type->isa('Moose::Meta::TypeConstraint')) {
463 $type = find_or_parse_type_constraint($type)
464 || __PACKAGE__->_throw_error("Cannot find or parse the type '$type'")
465 }
466
467 (ref $action eq 'CODE')
468 || __PACKAGE__->_throw_error("Match action must be a CODE ref, not $action");
469
470 if ($type->check($to_match)) {
471 local $_ = $to_match;
472 return $action->($to_match);
473 }
474 }
475 (defined $default)
476 || __PACKAGE__->_throw_error("No cases matched for $to_match");
477 {
478 local $_ = $to_match;
479 return $default->($to_match);
480 }
481}
482
483
484## --------------------------------------------------------
485## desugaring functions ...
486## --------------------------------------------------------
487
488
# spent 2.94ms (412µs+2.53) within Moose::Util::TypeConstraints::_create_type_constraint which was called 18 times, avg 163µs/call: # 17 times (381µs+2.33ms) by Moose::Util::TypeConstraints::subtype at line 330, avg 160µs/call # once (32µs+197µs) by Moose::Util::TypeConstraints::type at line 285
sub _create_type_constraint ($$$;$$) {
489271335µs my $name = shift;
490 my $parent = shift;
491 my $check = shift;
492 my $message = shift;
493 my $optimized = shift;
494
495 my $pkg_defined_in = scalar( caller(1) );
496
497 if ( defined $name ) {
498 my $type = $REGISTRY->get_type_constraint($name);
# spent 105µs making 18 calls to Moose::Meta::TypeConstraint::Registry::get_type_constraint, avg 6µs/call
499
500 ( $type->_package_defined_in eq $pkg_defined_in )
501 || _confess(
502 "The type constraint '$name' has already been created in "
503 . $type->_package_defined_in
504 . " and cannot be created again in "
505 . $pkg_defined_in )
506 if defined $type;
507
508 $name =~ /^[\w:\.]+$/
# spent 40µs making 18 calls to Moose::Util::TypeConstraints::CORE:match, avg 2µs/call
509 or die qq{$name contains invalid characters for a type name.}
510 . qq{ Names can contain alphanumeric character, ":", and "."\n};
511 }
512
513 my %opts = (
514 name => $name,
515 package_defined_in => $pkg_defined_in,
516
517 ( $check ? ( constraint => $check ) : () ),
518 ( $message ? ( message => $message ) : () ),
519 ( $optimized ? ( optimized => $optimized ) : () ),
520 );
521
522 my $constraint;
523132µs681.87ms if (
# spent 1.09ms making 17 calls to Moose::Meta::TypeConstraint::create_child_type, avg 64µs/call # spent 707µs making 17 calls to Moose::Util::TypeConstraints::find_or_create_isa_type_constraint, avg 42µs/call # spent 63µs making 17 calls to Moose::Meta::TypeConstraint::__ANON__[Moose/Meta/TypeConstraint.pm:8], avg 4µs/call # spent 10µs making 17 calls to Scalar::Util::blessed, avg 600ns/call
524 defined $parent
525 and $parent
526 = blessed $parent
527 ? $parent
528 : find_or_create_isa_type_constraint($parent)
529 ) {
530 $constraint = $parent->create_child_type(%opts);
531 }
532 else {
533 $constraint = Moose::Meta::TypeConstraint->new(%opts);
# spent 145µs making 1 call to Moose::Meta::TypeConstraint::new
534 }
535
536 $REGISTRY->add_type_constraint($constraint)
# spent 371µs making 18 calls to Moose::Meta::TypeConstraint::Registry::add_type_constraint, avg 21µs/call
537 if defined $name;
538
539 return $constraint;
540}
541
542sub _install_type_coercions ($$) {
543 my ( $type_name, $coercion_map ) = @_;
544 my $type = find_type_constraint($type_name);
545 ( defined $type )
546 || __PACKAGE__->_throw_error(
547 "Cannot find type '$type_name', perhaps you forgot to load it");
548 if ( $type->has_coercion ) {
549 $type->coercion->add_type_coercions(@$coercion_map);
550 }
551 else {
552 my $type_coercion = Moose::Meta::TypeCoercion->new(
553 type_coercion_map => $coercion_map,
554 type_constraint => $type
555 );
556 $type->coercion($type_coercion);
557 }
558}
559
560## --------------------------------------------------------
561## type notation parsing ...
562## --------------------------------------------------------
563
564{
565
566 # All I have to say is mugwump++ cause I know
567 # do not even have enough regexp-fu to be able
568 # to have written this (I can only barely
569 # understand it as it is)
570 # - SL
571
5724215µs6876µs
# spent 860µs (813+47) within Moose::Util::TypeConstraints::BEGIN@572 which was called # once (813µs+47µs) by Moose::Meta::Attribute::BEGIN@18 at line 572
use re "eval";
# spent 860µs making 1 call to Moose::Util::TypeConstraints::BEGIN@572 # spent 14µs making 1 call to re::import # spent 2µs making 4 calls to Regexp::DESTROY, avg 475ns/call
573
57419µs15µs my $valid_chars = qr{[\w:\.]};
# spent 5µs making 1 call to Moose::Util::TypeConstraints::CORE:qr
575118µs213µs my $type_atom = qr{ (?>$valid_chars+) }x;
# spent 12µs making 1 call to Moose::Util::TypeConstraints::CORE:regcomp # spent 1µs making 1 call to Moose::Util::TypeConstraints::CORE:qr
57612µs1700ns my $ws = qr{ (?>\s*) }x;
# spent 700ns making 1 call to Moose::Util::TypeConstraints::CORE:qr
577
5781100ns my $any;
579
580145µs232µs my $type = qr{ $type_atom (?: \[ $ws (??{$any}) $ws \] )? }x;
# spent 30µs making 1 call to Moose::Util::TypeConstraints::CORE:regcomp # spent 2µs making 1 call to Moose::Util::TypeConstraints::CORE:qr
581137µs231µs my $type_capture_parts
# spent 30µs making 1 call to Moose::Util::TypeConstraints::CORE:regcomp # spent 1µs making 1 call to Moose::Util::TypeConstraints::CORE:qr
582 = qr{ ($type_atom) (?: \[ $ws ((??{$any})) $ws \] )? }x;
583136µs230µs my $type_with_parameter
# spent 29µs making 1 call to Moose::Util::TypeConstraints::CORE:regcomp # spent 1µs making 1 call to Moose::Util::TypeConstraints::CORE:qr
584 = qr{ $type_atom \[ $ws (??{$any}) $ws \] }x;
585
586112µs28µs my $op_union = qr{ $ws \| $ws }x;
# spent 8µs making 1 call to Moose::Util::TypeConstraints::CORE:regcomp # spent 900ns making 1 call to Moose::Util::TypeConstraints::CORE:qr
587164µs256µs my $union = qr{ $type (?> (?: $op_union $type )+ ) }x;
# spent 55µs making 1 call to Moose::Util::TypeConstraints::CORE:regcomp # spent 1µs making 1 call to Moose::Util::TypeConstraints::CORE:qr
588
589189µs267µs $any = qr{ $type | $union }x;
# spent 66µs making 1 call to Moose::Util::TypeConstraints::CORE:regcomp # spent 1µs making 1 call to Moose::Util::TypeConstraints::CORE:qr
590
591 sub _parse_parameterized_type_constraint {
592362µs241µs
# spent 25µs (10+16) within Moose::Util::TypeConstraints::BEGIN@592 which was called # once (10µs+16µs) by Moose::Meta::Attribute::BEGIN@18 at line 592
{ no warnings 'void'; $any; } # force capture of interpolated lexical
# spent 25µs making 1 call to Moose::Util::TypeConstraints::BEGIN@592 # spent 16µs making 1 call to warnings::unimport
593 $_[0] =~ m{ $type_capture_parts }x;
594 return ( $1, $2 );
595 }
596
597 sub _detect_parameterized_type_constraint {
598344µs228µs
# spent 19µs (10+9) within Moose::Util::TypeConstraints::BEGIN@598 which was called # once (10µs+9µs) by Moose::Meta::Attribute::BEGIN@18 at line 598
{ no warnings 'void'; $any; } # force capture of interpolated lexical
# spent 19µs making 1 call to Moose::Util::TypeConstraints::BEGIN@598 # spent 9µs making 1 call to warnings::unimport
599 $_[0] =~ m{ ^ $type_with_parameter $ }x;
600 }
601
602 sub _parse_type_constraint_union {
603390µs223µs
# spent 15µs (7+8) within Moose::Util::TypeConstraints::BEGIN@603 which was called # once (7µs+8µs) by Moose::Meta::Attribute::BEGIN@18 at line 603
{ no warnings 'void'; $any; } # force capture of interpolated lexical
# spent 15µs making 1 call to Moose::Util::TypeConstraints::BEGIN@603 # spent 8µs making 1 call to warnings::unimport
604 my $given = shift;
605 my @rv;
606 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
607 push @rv => $1;
608 }
609 ( pos($given) eq length($given) )
610 || __PACKAGE__->_throw_error( "'$given' didn't parse (parse-pos="
611 . pos($given)
612 . " and str-length="
613 . length($given)
614 . ")" );
615 @rv;
616 }
617
618 sub _detect_type_constraint_union {
61931.16ms234µs
# spent 24µs (14+10) within Moose::Util::TypeConstraints::BEGIN@619 which was called # once (14µs+10µs) by Moose::Meta::Attribute::BEGIN@18 at line 619
{ no warnings 'void'; $any; } # force capture of interpolated lexical
# spent 24µs making 1 call to Moose::Util::TypeConstraints::BEGIN@619 # spent 10µs making 1 call to warnings::unimport
620 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
621 }
622}
623
624## --------------------------------------------------------
625# define some basic built-in types
626## --------------------------------------------------------
627
628# By making these classes immutable before creating all the types we
629# below, we avoid repeatedly calling the slow MOP-based accessors.
630$_->make_immutable(
63198µs96µs inline_constructor => 1,
# spent 6µs making 9 calls to Class::MOP::Class::is_mutable, avg 633ns/call
632 constructor_name => "_new",
633
634 # these are Class::MOP accessors, so they need inlining
635 inline_accessors => 1
6361028µs1816.7ms ) for grep { $_->is_mutable }
# spent 16.7ms making 9 calls to Class::MOP::Class::make_immutable, avg 1.86ms/call # spent 31µs making 9 calls to Class::MOP::class_of, avg 3µs/call
637 map { Class::MOP::class_of($_) }
638 qw(
639 Moose::Meta::TypeConstraint
640 Moose::Meta::TypeConstraint::Union
641 Moose::Meta::TypeConstraint::Parameterized
642 Moose::Meta::TypeConstraint::Parameterizable
643 Moose::Meta::TypeConstraint::Class
644 Moose::Meta::TypeConstraint::Role
645 Moose::Meta::TypeConstraint::Enum
646 Moose::Meta::TypeConstraint::DuckType
647 Moose::Meta::TypeConstraint::Registry
64810s);
649
65018µs2285µstype 'Any' => where {1}; # meta-type including all
# spent 282µs making 1 call to Moose::Util::TypeConstraints::type # spent 3µs making 1 call to Moose::Util::TypeConstraints::where
65116µs2290µssubtype 'Item' => as 'Any'; # base-type
# spent 286µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 4µs making 1 call to Moose::Util::TypeConstraints::as
652
65316µs3227µssubtype 'Undef' => as 'Item' => where { !defined($_) };
# spent 223µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where
65417µs3238µssubtype 'Defined' => as 'Item' => where { defined($_) };
# spent 234µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where
655
656subtype 'Bool' => as 'Item' =>
65717µs3224µs where { !defined($_) || $_ eq "" || "$_" eq '1' || "$_" eq '0' };
# spent 220µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where
658
659subtype 'Value' => as 'Defined' => where { !ref($_) } =>
660110µs4215µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Value;
# spent 209µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::optimize_as # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where
661
662subtype 'Ref' => as 'Defined' => where { ref($_) } =>
66319µs4179µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Ref;
# spent 175µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
664
665subtype 'Str' => as 'Value' => where { ref(\$_) eq 'SCALAR' } =>
66619µs4180µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Str;
# spent 175µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
667
668subtype 'Num' => as 'Str' =>
669 where { Scalar::Util::looks_like_number($_) } =>
67019µs4165µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Num;
# spent 160µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
671
672subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } =>
67318µs4163µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int;
# spent 158µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
674
675subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
67618µs4179µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
# spent 174µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
677subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } =>
67819µs4173µs optimize_as
# spent 168µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
679 \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
680subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
68119µs4171µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
# spent 166µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
682
683# NOTE:
684# scalar filehandles are GLOB refs,
685# but a GLOB ref is not always a filehandle
686subtype 'FileHandle' => as 'GlobRef' => where {
687 Scalar::Util::openhandle($_) || ( blessed($_) && $_->isa("IO::Handle") );
68818µs4166µs} => optimize_as
# spent 161µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
689 \&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
690
691# NOTE:
692# blessed(qr/.../) returns true,.. how odd
693subtype 'Object' => as 'Ref' =>
694 where { blessed($_) && blessed($_) ne 'Regexp' } =>
69518µs4173µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
# spent 168µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
696
697# This type is deprecated.
698subtype 'Role' => as 'Object' => where { $_->can('does') } =>
69918µs4166µs optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Role;
# spent 161µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
700
70112µsmy $_class_name_checker = sub { };
702
703subtype 'ClassName' => as 'Str' =>
70418µs4171µs where { Class::MOP::is_class_loaded($_) } => optimize_as
# spent 167µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 1µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
705 \&Moose::Util::TypeConstraints::OptimizedConstraints::ClassName;
706
707subtype 'RoleName' => as 'ClassName' => where {
708 (Class::MOP::class_of($_) || return)->isa('Moose::Meta::Role');
70917µs4164µs} => optimize_as
# spent 160µs making 1 call to Moose::Util::TypeConstraints::subtype # spent 2µs making 1 call to Moose::Util::TypeConstraints::as # spent 2µs making 1 call to Moose::Util::TypeConstraints::where # spent 1µs making 1 call to Moose::Util::TypeConstraints::optimize_as
710 \&Moose::Util::TypeConstraints::OptimizedConstraints::RoleName;
711
712## --------------------------------------------------------
713# parameterizable types ...
714
715$REGISTRY->add_type_constraint(
716 Moose::Meta::TypeConstraint::Parameterizable->new(
717 name => 'ScalarRef',
718 package_defined_in => __PACKAGE__,
719 parent => find_type_constraint('Ref'),
720 constraint => sub { ref($_) eq 'SCALAR' || ref($_) eq 'REF' },
721 optimized =>
722 \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef,
723 constraint_generator => sub {
724 my $type_parameter = shift;
725 my $check = $type_parameter->_compiled_type_constraint;
726 return sub {
727 return $check->(${ $_ });
728 };
729 }
730 )
731115µs3173µs);
# spent 132µs making 1 call to Moose::Meta::TypeConstraint::new # spent 24µs making 1 call to Moose::Meta::TypeConstraint::Registry::add_type_constraint # spent 16µs making 1 call to Moose::Util::TypeConstraints::find_type_constraint
732
733$REGISTRY->add_type_constraint(
734 Moose::Meta::TypeConstraint::Parameterizable->new(
735 name => 'ArrayRef',
736 package_defined_in => __PACKAGE__,
737 parent => find_type_constraint('Ref'),
738 constraint => sub { ref($_) eq 'ARRAY' },
739 optimized =>
740 \&Moose::Util::TypeConstraints::OptimizedConstraints::ArrayRef,
741 constraint_generator => sub {
742 my $type_parameter = shift;
743 my $check = $type_parameter->_compiled_type_constraint;
744 return sub {
745 foreach my $x (@$_) {
746 ( $check->($x) ) || return;
747 }
748 1;
749 }
750 }
751 )
752110µs384µs);
# spent 49µs making 1 call to Moose::Meta::TypeConstraint::new # spent 19µs making 1 call to Moose::Meta::TypeConstraint::Registry::add_type_constraint # spent 16µs making 1 call to Moose::Util::TypeConstraints::find_type_constraint
753
754$REGISTRY->add_type_constraint(
755 Moose::Meta::TypeConstraint::Parameterizable->new(
756 name => 'HashRef',
757 package_defined_in => __PACKAGE__,
758 parent => find_type_constraint('Ref'),
759 constraint => sub { ref($_) eq 'HASH' },
760 optimized =>
761 \&Moose::Util::TypeConstraints::OptimizedConstraints::HashRef,
762 constraint_generator => sub {
763 my $type_parameter = shift;
764 my $check = $type_parameter->_compiled_type_constraint;
765 return sub {
766 foreach my $x ( values %$_ ) {
767 ( $check->($x) ) || return;
768 }
769 1;
770 }
771 }
772 )
773110µs375µs);
# spent 41µs making 1 call to Moose::Meta::TypeConstraint::new # spent 19µs making 1 call to Moose::Meta::TypeConstraint::Registry::add_type_constraint # spent 16µs making 1 call to Moose::Util::TypeConstraints::find_type_constraint
774
775$REGISTRY->add_type_constraint(
776 Moose::Meta::TypeConstraint::Parameterizable->new(
777 name => 'Maybe',
778 package_defined_in => __PACKAGE__,
779 parent => find_type_constraint('Item'),
780 constraint => sub {1},
781 constraint_generator => sub {
782 my $type_parameter = shift;
783 my $check = $type_parameter->_compiled_type_constraint;
784 return sub {
785 return 1 if not( defined($_) ) || $check->($_);
786 return;
787 }
788 }
789 )
790113µs3128µs);
# spent 93µs making 1 call to Moose::Meta::TypeConstraint::new # spent 19µs making 1 call to Moose::Meta::TypeConstraint::Registry::add_type_constraint # spent 16µs making 1 call to Moose::Util::TypeConstraints::find_type_constraint
791
792my @PARAMETERIZABLE_TYPES
79357µs417µs = map { $REGISTRY->get_type_constraint($_) } qw[ScalarRef ArrayRef HashRef Maybe];
# spent 17µs making 4 calls to Moose::Meta::TypeConstraint::Registry::get_type_constraint, avg 4µs/call
794
795sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES}
796
797sub add_parameterizable_type {
798 my $type = shift;
799 ( blessed $type
800 && $type->isa('Moose::Meta::TypeConstraint::Parameterizable') )
801 || __PACKAGE__->_throw_error(
802 "Type must be a Moose::Meta::TypeConstraint::Parameterizable not $type"
803 );
804 push @PARAMETERIZABLE_TYPES => $type;
805}
806
807## --------------------------------------------------------
808# end of built-in types ...
809## --------------------------------------------------------
810
811{
812212µs113µs my @BUILTINS = list_all_type_constraints();
813 sub list_all_builtin_type_constraints {@BUILTINS}
814}
815
816sub _throw_error {
817 shift;
818 require Moose;
819 unshift @_, 'Moose';
820 goto &Moose::throw_error;
821}
822
8231168µs1;
824
825__END__
826
827=pod
828
829=head1 NAME
830
831Moose::Util::TypeConstraints - Type constraint system for Moose
832
833=head1 SYNOPSIS
834
835 use Moose::Util::TypeConstraints;
836
837 subtype 'Natural'
838 => as 'Int'
839 => where { $_ > 0 };
840
841 subtype 'NaturalLessThanTen'
842 => as 'Natural'
843 => where { $_ < 10 }
844 => message { "This number ($_) is not less than ten!" };
845
846 coerce 'Num'
847 => from 'Str'
848 => via { 0+$_ };
849
850 enum 'RGBColors' => qw(red green blue);
851
852 no Moose::Util::TypeConstraints;
853
854=head1 DESCRIPTION
855
856This module provides Moose with the ability to create custom type
857constraints to be used in attribute definition.
858
859=head2 Important Caveat
860
861This is B<NOT> a type system for Perl 5. These are type constraints,
862and they are not used by Moose unless you tell it to. No type
863inference is performed, expressions are not typed, etc. etc. etc.
864
865A type constraint is at heart a small "check if a value is valid"
866function. A constraint can be associated with an attribute. This
867simplifies parameter validation, and makes your code clearer to read,
868because you can refer to constraints by name.
869
870=head2 Slightly Less Important Caveat
871
872It is B<always> a good idea to quote your type names.
873
874This prevents Perl from trying to execute the call as an indirect
875object call. This can be an issue when you have a subtype with the
876same name as a valid class.
877
878For instance:
879
880 subtype DateTime => as Object => where { $_->isa('DateTime') };
881
882will I<just work>, while this:
883
884 use DateTime;
885 subtype DateTime => as Object => where { $_->isa('DateTime') };
886
887will fail silently and cause many headaches. The simple way to solve
888this, as well as future proof your subtypes from classes which have
889yet to have been created, is to quote the type name:
890
891 use DateTime;
892 subtype 'DateTime' => as 'Object' => where { $_->isa('DateTime') };
893
894=head2 Default Type Constraints
895
896This module also provides a simple hierarchy for Perl 5 types, here is
897that hierarchy represented visually.
898
899 Any
900 Item
901 Bool
902 Maybe[`a]
903 Undef
904 Defined
905 Value
906 Str
907 Num
908 Int
909 ClassName
910 RoleName
911 Ref
912 ScalarRef[`a]
913 ArrayRef[`a]
914 HashRef[`a]
915 CodeRef
916 RegexpRef
917 GlobRef
918 FileHandle
919 Object
920
921B<NOTE:> Any type followed by a type parameter C<[`a]> can be
922parameterized, this means you can say:
923
924 ArrayRef[Int] # an array of integers
925 HashRef[CodeRef] # a hash of str to CODE ref mappings
926 ScalarRef[Int] # a reference to an integer
927 Maybe[Str] # value may be a string, may be undefined
928
929If Moose finds a name in brackets that it does not recognize as an
930existing type, it assumes that this is a class name, for example
931C<ArrayRef[DateTime]>.
932
933B<NOTE:> Unless you parameterize a type, then it is invalid to include
934the square brackets. I.e. C<ArrayRef[]> will be treated as a new type
935name, I<not> as a parameterization of C<ArrayRef>.
936
937B<NOTE:> The C<Undef> type constraint for the most part works
938correctly now, but edge cases may still exist, please use it
939sparingly.
940
941B<NOTE:> The C<ClassName> type constraint does a complex package
942existence check. This means that your class B<must> be loaded for this
943type constraint to pass.
944
945B<NOTE:> The C<RoleName> constraint checks a string is a I<package
946name> which is a role, like C<'MyApp::Role::Comparable'>.
947
948=head2 Type Constraint Naming
949
950Type name declared via this module can only contain alphanumeric
951characters, colons (:), and periods (.).
952
953Since the types created by this module are global, it is suggested
954that you namespace your types just as you would namespace your
955modules. So instead of creating a I<Color> type for your
956B<My::Graphics> module, you would call the type
957I<My::Graphics::Types::Color> instead.
958
959=head2 Use with Other Constraint Modules
960
961This module can play nicely with other constraint modules with some
962slight tweaking. The C<where> clause in types is expected to be a
963C<CODE> reference which checks it's first argument and returns a
964boolean. Since most constraint modules work in a similar way, it
965should be simple to adapt them to work with Moose.
966
967For instance, this is how you could use it with
968L<Declare::Constraints::Simple> to declare a completely new type.
969
970 type 'HashOfArrayOfObjects',
971 {
972 where => IsHashRef(
973 -keys => HasLength,
974 -values => IsArrayRef(IsObject)
975 )
976 };
977
978For more examples see the F<t/200_examples/004_example_w_DCS.t> test
979file.
980
981Here is an example of using L<Test::Deep> and it's non-test
982related C<eq_deeply> function.
983
984 type 'ArrayOfHashOfBarsAndRandomNumbers'
985 => where {
986 eq_deeply($_,
987 array_each(subhashof({
988 bar => isa('Bar'),
989 random_number => ignore()
990 })))
991 };
992
993For a complete example see the
994F<t/200_examples/005_example_w_TestDeep.t> test file.
995
996=head1 FUNCTIONS
997
998=head2 Type Constraint Constructors
999
1000The following functions are used to create type constraints. They
1001will also register the type constraints your create in a global
1002registry that is used to look types up by name.
1003
1004See the L<SYNOPSIS> for an example of how to use these.
1005
1006=over 4
1007
1008=item B<< subtype 'Name' => as 'Parent' => where { } ... >>
1009
1010This creates a named subtype.
1011
1012If you provide a parent that Moose does not recognize, it will
1013automatically create a new class type constraint for this name.
1014
1015When creating a named type, the C<subtype> function should either be
1016called with the sugar helpers (C<where>, C<message>, etc), or with a
1017name and a hashref of parameters:
1018
1019 subtype( 'Foo', { where => ..., message => ... } );
1020
1021The valid hashref keys are C<as> (the parent), C<where>, C<message>,
1022and C<optimize_as>.
1023
1024=item B<< subtype as 'Parent' => where { } ... >>
1025
1026This creates an unnamed subtype and will return the type
1027constraint meta-object, which will be an instance of
1028L<Moose::Meta::TypeConstraint>.
1029
1030When creating an anonymous type, the C<subtype> function should either
1031be called with the sugar helpers (C<where>, C<message>, etc), or with
1032just a hashref of parameters:
1033
1034 subtype( { where => ..., message => ... } );
1035
1036=item B<class_type ($class, ?$options)>
1037
1038Creates a new subtype of C<Object> with the name C<$class> and the
1039metaclass L<Moose::Meta::TypeConstraint::Class>.
1040
1041=item B<role_type ($role, ?$options)>
1042
1043Creates a C<Role> type constraint with the name C<$role> and the
1044metaclass L<Moose::Meta::TypeConstraint::Role>.
1045
1046=item B<maybe_type ($type)>
1047
1048Creates a type constraint for either C<undef> or something of the
1049given type.
1050
1051=item B<duck_type ($name, \@methods)>
1052
1053This will create a subtype of Object and test to make sure the value
1054C<can()> do the methods in C<\@methods>.
1055
1056This is intended as an easy way to accept non-Moose objects that
1057provide a certain interface. If you're using Moose classes, we
1058recommend that you use a C<requires>-only Role instead.
1059
1060=item B<duck_type (\@methods)>
1061
1062If passed an ARRAY reference as the only parameter instead of the
1063C<$name>, C<\@methods> pair, this will create an unnamed duck type.
1064This can be used in an attribute definition like so:
1065
1066 has 'cache' => (
1067 is => 'ro',
1068 isa => duck_type( [qw( get_set )] ),
1069 );
1070
1071=item B<enum ($name, \@values)>
1072
1073This will create a basic subtype for a given set of strings.
1074The resulting constraint will be a subtype of C<Str> and
1075will match any of the items in C<\@values>. It is case sensitive.
1076See the L<SYNOPSIS> for a simple example.
1077
1078B<NOTE:> This is not a true proper enum type, it is simply
1079a convenient constraint builder.
1080
1081=item B<enum (\@values)>
1082
1083If passed an ARRAY reference as the only parameter instead of the
1084C<$name>, C<\@values> pair, this will create an unnamed enum. This
1085can then be used in an attribute definition like so:
1086
1087 has 'sort_order' => (
1088 is => 'ro',
1089 isa => enum([qw[ ascending descending ]]),
1090 );
1091
1092=item B<as 'Parent'>
1093
1094This is just sugar for the type constraint construction syntax.
1095
1096It takes a single argument, which is the name of a parent type.
1097
1098=item B<where { ... }>
1099
1100This is just sugar for the type constraint construction syntax.
1101
1102It takes a subroutine reference as an argument. When the type
1103constraint is tested, the reference is run with the value to be tested
1104in C<$_>. This reference should return true or false to indicate
1105whether or not the constraint check passed.
1106
1107=item B<message { ... }>
1108
1109This is just sugar for the type constraint construction syntax.
1110
1111It takes a subroutine reference as an argument. When the type
1112constraint fails, then the code block is run with the value provided
1113in C<$_>. This reference should return a string, which will be used in
1114the text of the exception thrown.
1115
1116=item B<optimize_as { ... }>
1117
1118This can be used to define a "hand optimized" version of your
1119type constraint which can be used to avoid traversing a subtype
1120constraint hierarchy.
1121
1122B<NOTE:> You should only use this if you know what you are doing,
1123all the built in types use this, so your subtypes (assuming they
1124are shallow) will not likely need to use this.
1125
1126=item B<< type 'Name' => where { } ... >>
1127
1128This creates a base type, which has no parent.
1129
1130The C<type> function should either be called with the sugar helpers
1131(C<where>, C<message>, etc), or with a name and a hashref of
1132parameters:
1133
1134 type( 'Foo', { where => ..., message => ... } );
1135
1136The valid hashref keys are C<where>, C<message>, and C<optimize_as>.
1137
1138=back
1139
1140=head2 Type Constraint Utilities
1141
1142=over 4
1143
1144=item B<< match_on_type $value => ( $type => \&action, ... ?\&default ) >>
1145
1146This is a utility function for doing simple type based dispatching similar to
1147match/case in OCaml and case/of in Haskell. It is not as featureful as those
1148languages, nor does not it support any kind of automatic destructuring
1149bind. Here is a simple Perl pretty printer dispatching over the core Moose
1150types.
1151
1152 sub ppprint {
1153 my $x = shift;
1154 match_on_type $x => (
1155 HashRef => sub {
1156 my $hash = shift;
1157 '{ '
1158 . (
1159 join ", " => map { $_ . ' => ' . ppprint( $hash->{$_} ) }
1160 sort keys %$hash
1161 ) . ' }';
1162 },
1163 ArrayRef => sub {
1164 my $array = shift;
1165 '[ ' . ( join ", " => map { ppprint($_) } @$array ) . ' ]';
1166 },
1167 CodeRef => sub {'sub { ... }'},
1168 RegexpRef => sub { 'qr/' . $_ . '/' },
1169 GlobRef => sub { '*' . B::svref_2object($_)->NAME },
1170 Object => sub { $_->can('to_string') ? $_->to_string : $_ },
1171 ScalarRef => sub { '\\' . ppprint( ${$_} ) },
1172 Num => sub {$_},
1173 Str => sub { '"' . $_ . '"' },
1174 Undef => sub {'undef'},
1175 => sub { die "I don't know what $_ is" }
1176 );
1177 }
1178
1179Or a simple JSON serializer:
1180
1181 sub to_json {
1182 my $x = shift;
1183 match_on_type $x => (
1184 HashRef => sub {
1185 my $hash = shift;
1186 '{ '
1187 . (
1188 join ", " =>
1189 map { '"' . $_ . '" : ' . to_json( $hash->{$_} ) }
1190 sort keys %$hash
1191 ) . ' }';
1192 },
1193 ArrayRef => sub {
1194 my $array = shift;
1195 '[ ' . ( join ", " => map { to_json($_) } @$array ) . ' ]';
1196 },
1197 Num => sub {$_},
1198 Str => sub { '"' . $_ . '"' },
1199 Undef => sub {'null'},
1200 => sub { die "$_ is not acceptable json type" }
1201 );
1202 }
1203
1204The matcher is done by mapping a C<$type> to an C<\&action>. The C<$type> can
1205be either a string type or a L<Moose::Meta::TypeConstraint> object, and
1206C<\&action> is a subroutine reference. This function will dispatch on the
1207first match for C<$value>. It is possible to have a catch-all by providing an
1208additional subroutine reference as the final argument to C<match_on_type>.
1209
1210=back
1211
1212=head2 Type Coercion Constructors
1213
1214You can define coercions for type constraints, which allow you to
1215automatically transform values to something valid for the type
1216constraint. If you ask your accessor to coerce, then Moose will run
1217the type-coercion code first, followed by the type constraint
1218check. This feature should be used carefully as it is very powerful
1219and could easily take off a limb if you are not careful.
1220
1221See the L<SYNOPSIS> for an example of how to use these.
1222
1223=over 4
1224
1225=item B<< coerce 'Name' => from 'OtherName' => via { ... } >>
1226
1227This defines a coercion from one type to another. The C<Name> argument
1228is the type you are coercing I<to>.
1229
1230=item B<from 'OtherName'>
1231
1232This is just sugar for the type coercion construction syntax.
1233
1234It takes a single type name (or type object), which is the type being
1235coerced I<from>.
1236
1237=item B<via { ... }>
1238
1239This is just sugar for the type coercion construction syntax.
1240
1241It takes a subroutine reference. This reference will be called with
1242the value to be coerced in C<$_>. It is expected to return a new value
1243of the proper type for the coercion.
1244
1245=back
1246
1247=head2 Creating and Finding Type Constraints
1248
1249These are additional functions for creating and finding type
1250constraints. Most of these functions are not available for
1251importing. The ones that are importable as specified.
1252
1253=over 4
1254
1255=item B<find_type_constraint($type_name)>
1256
1257This function can be used to locate the L<Moose::Meta::TypeConstraint>
1258object for a named type.
1259
1260This function is importable.
1261
1262=item B<register_type_constraint($type_object)>
1263
1264This function will register a L<Moose::Meta::TypeConstraint> with the
1265global type registry.
1266
1267This function is importable.
1268
1269=item B<normalize_type_constraint_name($type_constraint_name)>
1270
1271This method takes a type constraint name and returns the normalized
1272form. This removes any whitespace in the string.
1273
1274=item B<create_type_constraint_union($pipe_separated_types | @type_constraint_names)>
1275
1276This can take a union type specification like C<'Int|ArrayRef[Int]'>,
1277or a list of names. It returns a new
1278L<Moose::Meta::TypeConstraint::Union> object.
1279
1280=item B<create_parameterized_type_constraint($type_name)>
1281
1282Given a C<$type_name> in the form of C<'BaseType[ContainerType]'>,
1283this will create a new L<Moose::Meta::TypeConstraint::Parameterized>
1284object. The C<BaseType> must exist already exist as a parameterizable
1285type.
1286
1287=item B<create_class_type_constraint($class, $options)>
1288
1289Given a class name this function will create a new
1290L<Moose::Meta::TypeConstraint::Class> object for that class name.
1291
1292The C<$options> is a hash reference that will be passed to the
1293L<Moose::Meta::TypeConstraint::Class> constructor (as a hash).
1294
1295=item B<create_role_type_constraint($role, $options)>
1296
1297Given a role name this function will create a new
1298L<Moose::Meta::TypeConstraint::Role> object for that role name.
1299
1300The C<$options> is a hash reference that will be passed to the
1301L<Moose::Meta::TypeConstraint::Role> constructor (as a hash).
1302
1303=item B<create_enum_type_constraint($name, $values)>
1304
1305Given a enum name this function will create a new
1306L<Moose::Meta::TypeConstraint::Enum> object for that enum name.
1307
1308=item B<create_duck_type_constraint($name, $methods)>
1309
1310Given a duck type name this function will create a new
1311L<Moose::Meta::TypeConstraint::DuckType> object for that enum name.
1312
1313=item B<find_or_parse_type_constraint($type_name)>
1314
1315Given a type name, this first attempts to find a matching constraint
1316in the global registry.
1317
1318If the type name is a union or parameterized type, it will create a
1319new object of the appropriate, but if given a "regular" type that does
1320not yet exist, it simply returns false.
1321
1322When given a union or parameterized type, the member or base type must
1323already exist.
1324
1325If it creates a new union or parameterized type, it will add it to the
1326global registry.
1327
1328=item B<find_or_create_isa_type_constraint($type_name)>
1329
1330=item B<find_or_create_does_type_constraint($type_name)>
1331
1332These functions will first call C<find_or_parse_type_constraint>. If
1333that function does not return a type, a new anonymous type object will
1334be created.
1335
1336The C<isa> variant will use C<create_class_type_constraint> and the
1337C<does> variant will use C<create_role_type_constraint>.
1338
1339=item B<get_type_constraint_registry>
1340
1341Returns the L<Moose::Meta::TypeConstraint::Registry> object which
1342keeps track of all type constraints.
1343
1344=item B<list_all_type_constraints>
1345
1346This will return a list of type constraint names in the global
1347registry. You can then fetch the actual type object using
1348C<find_type_constraint($type_name)>.
1349
1350=item B<list_all_builtin_type_constraints>
1351
1352This will return a list of builtin type constraints, meaning those
1353which are defined in this module. See the L<Default Type Constraints>
1354section for a complete list.
1355
1356=item B<export_type_constraints_as_functions>
1357
1358This will export all the current type constraints as functions into
1359the caller's namespace (C<Int()>, C<Str()>, etc). Right now, this is
1360mostly used for testing, but it might prove useful to others.
1361
1362=item B<get_all_parameterizable_types>
1363
1364This returns all the parameterizable types that have been registered,
1365as a list of type objects.
1366
1367=item B<add_parameterizable_type($type)>
1368
1369Adds C<$type> to the list of parameterizable types
1370
1371=back
1372
1373=head1 BUGS
1374
1375See L<Moose/BUGS> for details on reporting bugs.
1376
1377=head1 AUTHOR
1378
1379Stevan Little E<lt>stevan@iinteractive.comE<gt>
1380
1381=head1 COPYRIGHT AND LICENSE
1382
1383Copyright 2006-2010 by Infinity Interactive, Inc.
1384
1385L<http://www.iinteractive.com>
1386
1387This library is free software; you can redistribute it and/or modify
1388it under the same terms as Perl itself.
1389
1390=cut
# spent 40µs within Moose::Util::TypeConstraints::CORE:match which was called 18 times, avg 2µs/call: # 18 times (40µs+0s) by Moose::Util::TypeConstraints::_create_type_constraint at line 508 of Moose/Util/TypeConstraints.pm, avg 2µs/call
sub Moose::Util::TypeConstraints::CORE:match; # xsub
# spent 14µs within Moose::Util::TypeConstraints::CORE:qr which was called 9 times, avg 2µs/call: # once (5µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 574 of Moose/Util/TypeConstraints.pm # once (2µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 580 of Moose/Util/TypeConstraints.pm # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 589 of Moose/Util/TypeConstraints.pm # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 587 of Moose/Util/TypeConstraints.pm # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 581 of Moose/Util/TypeConstraints.pm # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 583 of Moose/Util/TypeConstraints.pm # once (1µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 575 of Moose/Util/TypeConstraints.pm # once (900ns+0s) by Moose::Meta::Attribute::BEGIN@18 at line 586 of Moose/Util/TypeConstraints.pm # once (700ns+0s) by Moose::Meta::Attribute::BEGIN@18 at line 576 of Moose/Util/TypeConstraints.pm
sub Moose::Util::TypeConstraints::CORE:qr; # xsub
# spent 230µs within Moose::Util::TypeConstraints::CORE:regcomp which was called 7 times, avg 33µs/call: # once (66µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 589 of Moose/Util/TypeConstraints.pm # once (55µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 587 of Moose/Util/TypeConstraints.pm # once (30µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 580 of Moose/Util/TypeConstraints.pm # once (30µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 581 of Moose/Util/TypeConstraints.pm # once (29µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 583 of Moose/Util/TypeConstraints.pm # once (12µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 575 of Moose/Util/TypeConstraints.pm # once (8µs+0s) by Moose::Meta::Attribute::BEGIN@18 at line 586 of Moose/Util/TypeConstraints.pm
sub Moose::Util::TypeConstraints::CORE:regcomp; # xsub
# spent 12µs within Moose::Util::TypeConstraints::CORE:subst which was called 17 times, avg 718ns/call: # 17 times (12µs+0s) by Moose::Util::TypeConstraints::normalize_type_constraint_name at line 237 of Moose/Util/TypeConstraints.pm, avg 718ns/call
sub Moose::Util::TypeConstraints::CORE:subst; # xsub