Filename | /Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Coercion.pm |
Statements | Executed 1368 statements in 6.35ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
58 | 3 | 3 | 1.65ms | 9.39ms | new | Type::Coercion::
58 | 1 | 1 | 394µs | 7.24ms | _preserve_type_constraint | Type::Coercion::
61 | 2 | 2 | 185µs | 235µs | is_anon | Type::Coercion::
2 | 2 | 2 | 89µs | 935µs | add_type_coercions | Type::Coercion::
56 | 4 | 3 | 66µs | 66µs | freeze | Type::Coercion::
70 | 4 | 2 | 57µs | 57µs | name | Type::Coercion::
56 | 5 | 2 | 57µs | 57µs | type_coercion_map | Type::Coercion::
52 | 2 | 1 | 47µs | 47µs | __ANON__[:28] | Type::Coercion::
2 | 2 | 1 | 46µs | 178µs | can_be_inlined | Type::Coercion::
1 | 1 | 1 | 45µs | 219µs | inline_coercion | Type::Coercion::
1 | 1 | 1 | 42µs | 42µs | BEGIN@3 | Type::Coercion::
1 | 1 | 1 | 39µs | 560µs | _build_compiled_coercion | Type::Coercion::
6 | 3 | 1 | 18µs | 24µs | type_constraint | Type::Coercion::
1 | 1 | 1 | 18µs | 83µs | BEGIN@5 | Type::Coercion::
3 | 1 | 1 | 17µs | 24µs | qualified_name | Type::Coercion::
5 | 3 | 1 | 15µs | 15µs | CORE:match (opcode) | Type::Coercion::
1 | 1 | 1 | 13µs | 16µs | __ANON__[:27] | Type::Coercion::
1 | 1 | 1 | 11µs | 60µs | BEGIN@15 | Type::Coercion::
3 | 2 | 1 | 11µs | 26µs | has_type_constraint | Type::Coercion::
6 | 4 | 3 | 9µs | 9µs | frozen | Type::Coercion::
3 | 1 | 1 | 8µs | 11µs | is_parameterizable | Type::Coercion::
1 | 1 | 1 | 7µs | 11µs | BEGIN@4 | Type::Coercion::
1 | 1 | 1 | 7µs | 567µs | compiled_coercion | Type::Coercion::
1 | 1 | 1 | 5µs | 9µs | AUTOLOAD | Type::Coercion::
1 | 1 | 1 | 5µs | 5µs | BEGIN@16 | Type::Coercion::
2 | 1 | 1 | 4µs | 4µs | _clear_compiled_coercion | Type::Coercion::
3 | 1 | 1 | 4µs | 4µs | has_library | Type::Coercion::
1 | 1 | 1 | 3µs | 3µs | BEGIN@7 | Type::Coercion::
3 | 1 | 1 | 3µs | 3µs | has_coercion_generator | Type::Coercion::
1 | 1 | 1 | 2µs | 2µs | BEGIN@14 | Type::Coercion::
1 | 1 | 1 | 2µs | 2µs | display_name | Type::Coercion::
0 | 0 | 0 | 0s | 0s | __ANON__[:262] | Type::Coercion::
0 | 0 | 0 | 0s | 0s | __ANON__[:33] | Type::Coercion::
0 | 0 | 0 | 0s | 0s | __ANON__[:46] | Type::Coercion::
0 | 0 | 0 | 0s | 0s | __ANON__[:500] | Type::Coercion::
0 | 0 | 0 | 0s | 0s | _build_display_name | Type::Coercion::
0 | 0 | 0 | 0s | 0s | _build_moose_coercion | Type::Coercion::
0 | 0 | 0 | 0s | 0s | _codelike_type_coercion_map | Type::Coercion::
0 | 0 | 0 | 0s | 0s | _compiled_type_coercion | Type::Coercion::
0 | 0 | 0 | 0s | 0s | _croak | Type::Coercion::
0 | 0 | 0 | 0s | 0s | _maybe_restore_type_constraint | Type::Coercion::
0 | 0 | 0 | 0s | 0s | _overload_coderef | Type::Coercion::
0 | 0 | 0 | 0s | 0s | _reparameterize | Type::Coercion::
0 | 0 | 0 | 0s | 0s | _source_type_union | Type::Coercion::
0 | 0 | 0 | 0s | 0s | _stringify_no_magic | Type::Coercion::
0 | 0 | 0 | 0s | 0s | add | Type::Coercion::
0 | 0 | 0 | 0s | 0s | assert_coerce | Type::Coercion::
0 | 0 | 0 | 0s | 0s | can | Type::Coercion::
0 | 0 | 0 | 0s | 0s | coerce | Type::Coercion::
0 | 0 | 0 | 0s | 0s | coercion_generator | Type::Coercion::
0 | 0 | 0 | 0s | 0s | has_coercion_for_type | Type::Coercion::
0 | 0 | 0 | 0s | 0s | has_coercion_for_value | Type::Coercion::
0 | 0 | 0 | 0s | 0s | has_parameters | Type::Coercion::
0 | 0 | 0 | 0s | 0s | i_really_want_to_unfreeze | Type::Coercion::
0 | 0 | 0 | 0s | 0s | is_parameterized | Type::Coercion::
0 | 0 | 0 | 0s | 0s | isa | Type::Coercion::
0 | 0 | 0 | 0s | 0s | library | Type::Coercion::
0 | 0 | 0 | 0s | 0s | meta | Type::Coercion::
0 | 0 | 0 | 0s | 0s | moose_coercion | Type::Coercion::
0 | 0 | 0 | 0s | 0s | parameterize | Type::Coercion::
0 | 0 | 0 | 0s | 0s | parameterized_from | Type::Coercion::
0 | 0 | 0 | 0s | 0s | parameters | Type::Coercion::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Type::Coercion; | ||||
2 | |||||
3 | 2 | 53µs | 1 | 42µs | # spent 42µs within Type::Coercion::BEGIN@3 which was called:
# once (42µs+0s) by Type::Tiny::_build_coercion at line 3 # spent 42µs making 1 call to Type::Coercion::BEGIN@3 |
4 | 2 | 25µs | 2 | 15µs | # spent 11µs (7+4) within Type::Coercion::BEGIN@4 which was called:
# once (7µs+4µs) by Type::Tiny::_build_coercion at line 4 # spent 11µs making 1 call to Type::Coercion::BEGIN@4
# spent 4µs making 1 call to strict::import |
5 | 2 | 53µs | 2 | 148µs | # spent 83µs (18+65) within Type::Coercion::BEGIN@5 which was called:
# once (18µs+65µs) by Type::Tiny::_build_coercion at line 5 # spent 83µs making 1 call to Type::Coercion::BEGIN@5
# spent 65µs making 1 call to warnings::import |
6 | |||||
7 | # spent 3µs within Type::Coercion::BEGIN@7 which was called:
# once (3µs+0s) by Type::Tiny::_build_coercion at line 10 | ||||
8 | 1 | 0s | $Type::Coercion::AUTHORITY = 'cpan:TOBYINK'; | ||
9 | 1 | 7µs | $Type::Coercion::VERSION = '2.000001'; | ||
10 | 1 | 35µs | 1 | 3µs | } # spent 3µs making 1 call to Type::Coercion::BEGIN@7 |
11 | |||||
12 | 1 | 2µs | $Type::Coercion::VERSION =~ tr/_//d; | ||
13 | |||||
14 | 2 | 19µs | 1 | 2µs | # spent 2µs within Type::Coercion::BEGIN@14 which was called:
# once (2µs+0s) by Type::Tiny::_build_coercion at line 14 # spent 2µs making 1 call to Type::Coercion::BEGIN@14 |
15 | 2 | 48µs | 2 | 109µs | # spent 60µs (11+49) within Type::Coercion::BEGIN@15 which was called:
# once (11µs+49µs) by Type::Tiny::_build_coercion at line 15 # spent 60µs making 1 call to Type::Coercion::BEGIN@15
# spent 49µs making 1 call to Exporter::import |
16 | 2 | 3.18ms | 1 | 5µs | # spent 5µs within Type::Coercion::BEGIN@16 which was called:
# once (5µs+0s) by Type::Tiny::_build_coercion at line 16 # spent 5µs making 1 call to Type::Coercion::BEGIN@16 |
17 | |||||
18 | sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak } | ||||
19 | |||||
20 | 1 | 2µs | require Type::Tiny; | ||
21 | |||||
22 | __PACKAGE__->Type::Tiny::_install_overloads( | ||||
23 | # spent 16µs (13+3) within Type::Coercion::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Coercion.pm:27] which was called:
# once (13µs+3µs) by Type::Coercion::_build_compiled_coercion at line 265 | ||||
24 | 1 | 14µs | 2 | 3µs | caller =~ m{^(Moo::HandleMoose|Sub::Quote)} # spent 2µs making 1 call to Type::Coercion::display_name
# spent 1µs making 1 call to Type::Coercion::CORE:match |
25 | ? $_[0]->_stringify_no_magic | ||||
26 | : $_[0]->display_name; | ||||
27 | }, | ||||
28 | 52 | 114µs | # spent 47µs within Type::Coercion::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Coercion.pm:28] which was called 52 times, avg 904ns/call:
# 48 times (47µs+0s) by Type::Tiny::has_coercion at line 472 of Type/Tiny.pm, avg 979ns/call
# 4 times (0s+0s) by Type::Tiny::coercion at line 439 of Type/Tiny.pm, avg 0s/call | ||
29 | 1 | 9µs | 1 | 31µs | q(&{}) => "_overload_coderef", # spent 31µs making 1 call to Type::Tiny::_install_overloads |
30 | ); | ||||
31 | |||||
32 | __PACKAGE__->Type::Tiny::_install_overloads( | ||||
33 | q(~~) => sub { $_[0]->has_coercion_for_value( $_[1] ) }, | ||||
34 | 1 | 3µs | 1 | 9µs | ) if Type::Tiny::SUPPORT_SMARTMATCH(); # spent 9µs making 1 call to Type::Tiny::_install_overloads |
35 | |||||
36 | sub _overload_coderef { | ||||
37 | my $self = shift; | ||||
38 | |||||
39 | if ( "Sub::Quote"->can( "quote_sub" ) && $self->can_be_inlined ) { | ||||
40 | $self->{_overload_coderef} = | ||||
41 | Sub::Quote::quote_sub( $self->inline_coercion( '$_[0]' ) ) | ||||
42 | if !$self->{_overload_coderef} || !$self->{_sub_quoted}++; | ||||
43 | } | ||||
44 | else { | ||||
45 | Scalar::Util::weaken( my $weak = $self ); | ||||
46 | $self->{_overload_coderef} ||= sub { $weak->coerce( @_ ) }; | ||||
47 | } | ||||
48 | |||||
49 | $self->{_overload_coderef}; | ||||
50 | } #/ sub _overload_coderef | ||||
51 | |||||
52 | # spent 9.39ms (1.65+7.74) within Type::Coercion::new which was called 58 times, avg 162µs/call:
# 54 times (1.59ms+7.44ms) by Type::Tiny::_build_coercion at line 503 of Type/Tiny.pm, avg 167µs/call
# 3 times (54µs+252µs) by Type::Library::add_coercion at line 274 of Type/Library.pm, avg 102µs/call
# once (6µs+47µs) by Types::Standard::Dict::__coercion_generator at line 251 of Types/Standard/Dict.pm | ||||
53 | 58 | 12µs | my $class = shift; | ||
54 | 58 | 75µs | my %params = ( @_ == 1 ) ? %{ $_[0] } : @_; | ||
55 | |||||
56 | 58 | 31µs | $params{name} = '__ANON__' unless exists( $params{name} ); | ||
57 | 58 | 40µs | my $C = delete( $params{type_coercion_map} ) || []; | ||
58 | 58 | 6µs | my $F = delete( $params{frozen} ); | ||
59 | |||||
60 | 58 | 27µs | my $self = bless \%params, $class; | ||
61 | 58 | 19µs | 1 | 198µs | $self->add_type_coercions( @$C ) if @$C; # spent 198µs making 1 call to Type::Coercion::add_type_coercions |
62 | 58 | 86µs | 58 | 7.24ms | $self->_preserve_type_constraint; # spent 7.24ms making 58 calls to Type::Coercion::_preserve_type_constraint, avg 125µs/call |
63 | 58 | 206µs | 58 | 60µs | Scalar::Util::weaken( $self->{type_constraint} ); # break ref cycle # spent 60µs making 58 calls to Scalar::Util::weaken, avg 1µs/call |
64 | 58 | 12µs | $self->{frozen} = $F if $F; | ||
65 | |||||
66 | 58 | 72µs | 58 | 229µs | unless ( $self->is_anon ) { # spent 229µs making 58 calls to Type::Coercion::is_anon, avg 4µs/call |
67 | |||||
68 | # First try a fast ASCII-only expression, but fall back to Unicode | ||||
69 | 3 | 16µs | 6 | 12µs | $self->name =~ /^_{0,2}[A-Z][A-Za-z0-9_]+$/sm # spent 10µs making 3 calls to Type::Coercion::CORE:match, avg 3µs/call
# spent 2µs making 3 calls to Type::Coercion::name, avg 667ns/call |
70 | or eval q( use 5.008; $self->name =~ /^_{0,2}\p{Lu}[\p{L}0-9_]+$/sm ) | ||||
71 | or _croak '"%s" is not a valid coercion name', $self->name; | ||||
72 | } | ||||
73 | |||||
74 | 58 | 116µs | return $self; | ||
75 | } #/ sub new | ||||
76 | |||||
77 | sub _stringify_no_magic { | ||||
78 | sprintf( | ||||
79 | '%s=%s(0x%08x)', blessed( $_[0] ), Scalar::Util::reftype( $_[0] ), | ||||
80 | Scalar::Util::refaddr( $_[0] ) | ||||
81 | ); | ||||
82 | } | ||||
83 | |||||
84 | 70 | 123µs | # spent 57µs within Type::Coercion::name which was called 70 times, avg 814ns/call:
# 61 times (50µs+0s) by Type::Coercion::is_anon at line 176, avg 820ns/call
# 3 times (3µs+0s) by Type::Coercion::qualified_name at line 171, avg 1µs/call
# 3 times (2µs+0s) by Type::Library::add_coercion at line 275 of Type/Library.pm, avg 667ns/call
# 3 times (2µs+0s) by Type::Coercion::new at line 69, avg 667ns/call | ||
85 | 1 | 3µs | # spent 2µs within Type::Coercion::display_name which was called:
# once (2µs+0s) by Type::Coercion::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Coercion.pm:27] at line 24 | ||
86 | sub library { $_[0]{library} } | ||||
87 | |||||
88 | # spent 24µs (18+6) within Type::Coercion::type_constraint which was called 6 times, avg 4µs/call:
# 3 times (10µs+5µs) by Type::Coercion::has_type_constraint at line 103, avg 5µs/call
# 2 times (6µs+1000ns) by Type::Coercion::can_be_inlined at line 318, avg 4µs/call
# once (2µs+0s) by Type::Coercion::inline_coercion at line 361 | ||||
89 | 6 | 23µs | 6 | 6µs | $_[0]{type_constraint} ||= $_[0]->_maybe_restore_type_constraint; # spent 6µs making 6 calls to Type::Tiny::__ANON__[Type/Tiny.pm:101], avg 1µs/call |
90 | } | ||||
91 | 56 | 118µs | # spent 57µs within Type::Coercion::type_coercion_map which was called 56 times, avg 1µs/call:
# 48 times (47µs+0s) by Type::Tiny::has_coercion at line 472 of Type/Tiny.pm, avg 979ns/call
# 4 times (6µs+0s) by Type::Coercion::add_type_coercions at line 250, avg 2µs/call
# 2 times (2µs+0s) by Type::Coercion::can_be_inlined at line 321, avg 1µs/call
# once (1µs+0s) by Type::Coercion::inline_coercion at line 352
# once (1µs+0s) by Type::Coercion::_build_compiled_coercion at line 261 | ||
92 | sub moose_coercion { $_[0]{moose_coercion} ||= $_[0]->_build_moose_coercion } | ||||
93 | |||||
94 | # spent 567µs (7+560) within Type::Coercion::compiled_coercion which was called:
# once (7µs+560µs) by Type::Tiny::exportables at line 1220 of Type/Tiny.pm | ||||
95 | 1 | 6µs | 1 | 560µs | $_[0]{compiled_coercion} ||= $_[0]->_build_compiled_coercion; # spent 560µs making 1 call to Type::Coercion::_build_compiled_coercion |
96 | } | ||||
97 | 6 | 16µs | # spent 9µs within Type::Coercion::frozen which was called 6 times, avg 2µs/call:
# 2 times (3µs+0s) by Type::Coercion::can_be_inlined at line 315, avg 2µs/call
# 2 times (3µs+0s) by Type::Coercion::add_type_coercions at line 234, avg 2µs/call
# once (2µs+0s) by Type::Library::make_immutable at line 319 of Type/Library.pm
# once (1µs+0s) by Type::Tiny::exportables at line 1220 of Type/Tiny.pm | ||
98 | sub coercion_generator { $_[0]{coercion_generator} } | ||||
99 | sub parameters { $_[0]{parameters} } | ||||
100 | sub parameterized_from { $_[0]{parameterized_from} } | ||||
101 | |||||
102 | 3 | 7µs | # spent 4µs within Type::Coercion::has_library which was called 3 times, avg 1µs/call:
# 3 times (4µs+0s) by Type::Coercion::qualified_name at line 167, avg 1µs/call | ||
103 | 3 | 16µs | 3 | 15µs | sub has_type_constraint { defined $_[0]->type_constraint } # sic # spent 15µs making 3 calls to Type::Coercion::type_constraint, avg 5µs/call |
104 | 3 | 7µs | # spent 3µs within Type::Coercion::has_coercion_generator which was called 3 times, avg 1µs/call:
# 3 times (3µs+0s) by Type::Coercion::is_parameterizable at line 426, avg 1µs/call | ||
105 | sub has_parameters { exists $_[0]{parameters} } | ||||
106 | |||||
107 | # spent 7.24ms (394µs+6.85) within Type::Coercion::_preserve_type_constraint which was called 58 times, avg 125µs/call:
# 58 times (394µs+6.85ms) by Type::Coercion::new at line 62, avg 125µs/call | ||||
108 | 58 | 17µs | my $self = shift; | ||
109 | $self->{_compiled_type_constraint_check} = | ||||
110 | $self->{type_constraint}->compiled_check | ||||
111 | 58 | 271µs | 116 | 6.85ms | if $self->{type_constraint}; # spent 6.79ms making 58 calls to Type::Tiny::compiled_check, avg 117µs/call
# spent 54µs making 58 calls to Type::Tiny::__ANON__[Type/Tiny.pm:101], avg 931ns/call |
112 | } | ||||
113 | |||||
114 | sub _maybe_restore_type_constraint { | ||||
115 | my $self = shift; | ||||
116 | if ( my $check = $self->{_compiled_type_constraint_check} ) { | ||||
117 | return Type::Tiny->new( constraint => $check ); | ||||
118 | } | ||||
119 | return; # uncoverable statement | ||||
120 | } | ||||
121 | |||||
122 | sub add { | ||||
123 | my $class = shift; | ||||
124 | my ( $x, $y, $swap ) = @_; | ||||
125 | |||||
126 | Types::TypeTiny::is_TypeTiny( $x ) and return $x->plus_fallback_coercions( $y ); | ||||
127 | Types::TypeTiny::is_TypeTiny( $y ) and return $y->plus_coercions( $x ); | ||||
128 | |||||
129 | _croak "Attempt to add $class to something that is not a $class" | ||||
130 | unless blessed( $x ) | ||||
131 | && blessed( $y ) | ||||
132 | && $x->isa( $class ) | ||||
133 | && $y->isa( $class ); | ||||
134 | |||||
135 | ( $y, $x ) = ( $x, $y ) if $swap; | ||||
136 | |||||
137 | my %opts; | ||||
138 | if ( $x->has_type_constraint | ||||
139 | and $y->has_type_constraint | ||||
140 | and $x->type_constraint == $y->type_constraint ) | ||||
141 | { | ||||
142 | $opts{type_constraint} = $x->type_constraint; | ||||
143 | } | ||||
144 | elsif ( $x->has_type_constraint and $y->has_type_constraint ) { | ||||
145 | |||||
146 | # require Type::Tiny::Union; | ||||
147 | # $opts{type_constraint} = "Type::Tiny::Union"->new( | ||||
148 | # type_constraints => [ $x->type_constraint, $y->type_constraint ], | ||||
149 | # ); | ||||
150 | } | ||||
151 | $opts{display_name} ||= "$x+$y"; | ||||
152 | delete $opts{display_name} if $opts{display_name} eq '__ANON__+__ANON__'; | ||||
153 | |||||
154 | my $new = $class->new( %opts ); | ||||
155 | $new->add_type_coercions( @{ $x->type_coercion_map } ); | ||||
156 | $new->add_type_coercions( @{ $y->type_coercion_map } ); | ||||
157 | return $new; | ||||
158 | } #/ sub add | ||||
159 | |||||
160 | sub _build_display_name { | ||||
161 | shift->name; | ||||
162 | } | ||||
163 | |||||
164 | # spent 24µs (17+7) within Type::Coercion::qualified_name which was called 3 times, avg 8µs/call:
# 3 times (17µs+7µs) by Eval::TypeTiny::type_to_coderef at line 169 of Eval/TypeTiny.pm, avg 8µs/call | ||||
165 | 3 | 0s | my $self = shift; | ||
166 | |||||
167 | 3 | 6µs | 3 | 4µs | if ( $self->has_library and not $self->is_anon ) { # spent 4µs making 3 calls to Type::Coercion::has_library, avg 1µs/call |
168 | return sprintf( "%s::%s", $self->library, $self->name ); | ||||
169 | } | ||||
170 | |||||
171 | 3 | 9µs | 3 | 3µs | return $self->name; # spent 3µs making 3 calls to Type::Coercion::name, avg 1µs/call |
172 | } | ||||
173 | |||||
174 | # spent 235µs (185+50) within Type::Coercion::is_anon which was called 61 times, avg 4µs/call:
# 58 times (180µs+49µs) by Type::Coercion::new at line 66, avg 4µs/call
# 3 times (5µs+1000ns) by Type::Library::add_coercion at line 279 of Type/Library.pm, avg 2µs/call | ||||
175 | 61 | 8µs | my $self = shift; | ||
176 | 61 | 1.13ms | 61 | 50µs | $self->name eq "__ANON__"; # spent 50µs making 61 calls to Type::Coercion::name, avg 820ns/call |
177 | } | ||||
178 | |||||
179 | # spent 4µs within Type::Coercion::_clear_compiled_coercion which was called 2 times, avg 2µs/call:
# 2 times (4µs+0s) by Type::Coercion::add_type_coercions at line 254, avg 2µs/call | ||||
180 | 2 | 1µs | delete $_[0]{_overload_coderef}; | ||
181 | 2 | 5µs | delete $_[0]{compiled_coercion}; | ||
182 | } | ||||
183 | |||||
184 | 112 | 115µs | # spent 66µs within Type::Coercion::freeze which was called 56 times, avg 1µs/call:
# 37 times (42µs+0s) by Type::Library::make_immutable at line 318 of Type/Library.pm, avg 1µs/call
# 14 times (19µs+0s) by Type::Tiny::parameterize at line 1082 of Type/Tiny.pm, avg 1µs/call
# 3 times (4µs+0s) by Type::Tiny::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Tiny.pm:1073] at line 1072 of Type/Tiny.pm, avg 1µs/call
# 2 times (1µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:732] at line 731 of Types/Standard.pm, avg 500ns/call | ||
185 | sub i_really_want_to_unfreeze { $_[0]{frozen} = 0; $_[0] } | ||||
186 | |||||
187 | sub coerce { | ||||
188 | my $self = shift; | ||||
189 | return $self->compiled_coercion->( @_ ); | ||||
190 | } | ||||
191 | |||||
192 | sub assert_coerce { | ||||
193 | my $self = shift; | ||||
194 | my $r = $self->coerce( @_ ); | ||||
195 | $self->type_constraint->assert_valid( $r ) | ||||
196 | if $self->has_type_constraint; | ||||
197 | return $r; | ||||
198 | } | ||||
199 | |||||
200 | sub has_coercion_for_type { | ||||
201 | my $self = shift; | ||||
202 | my $type = Types::TypeTiny::to_TypeTiny( $_[0] ); | ||||
203 | |||||
204 | return "0 but true" | ||||
205 | if $self->has_type_constraint | ||||
206 | && $type->is_a_type_of( $self->type_constraint ); | ||||
207 | |||||
208 | my $c = $self->type_coercion_map; | ||||
209 | for ( my $i = 0 ; $i <= $#$c ; $i += 2 ) { | ||||
210 | return !!1 if $type->is_a_type_of( $c->[$i] ); | ||||
211 | } | ||||
212 | return; | ||||
213 | } #/ sub has_coercion_for_type | ||||
214 | |||||
215 | sub has_coercion_for_value { | ||||
216 | my $self = shift; | ||||
217 | local $_ = $_[0]; | ||||
218 | |||||
219 | return "0 but true" | ||||
220 | if $self->has_type_constraint | ||||
221 | && $self->type_constraint->check( @_ ); | ||||
222 | |||||
223 | my $c = $self->type_coercion_map; | ||||
224 | for ( my $i = 0 ; $i <= $#$c ; $i += 2 ) { | ||||
225 | return !!1 if $c->[$i]->check( @_ ); | ||||
226 | } | ||||
227 | return; | ||||
228 | } #/ sub has_coercion_for_value | ||||
229 | |||||
230 | # spent 935µs (89+846) within Type::Coercion::add_type_coercions which was called 2 times, avg 468µs/call:
# once (31µs+706µs) by JSON::Schema::Modern::BEGIN@31 at line 234 of Types/Standard.pm
# once (58µs+140µs) by Type::Coercion::new at line 61 | ||||
231 | 2 | 0s | my $self = shift; | ||
232 | 2 | 3µs | my @args = @_; | ||
233 | |||||
234 | 2 | 5µs | 2 | 3µs | _croak "Attempt to add coercion code to a Type::Coercion which has been frozen" # spent 3µs making 2 calls to Type::Coercion::frozen, avg 2µs/call |
235 | if $self->frozen; | ||||
236 | |||||
237 | 2 | 1µs | while ( @args ) { | ||
238 | 4 | 8µs | 4 | 28µs | my $type = Types::TypeTiny::to_TypeTiny( shift @args ); # spent 28µs making 4 calls to Types::TypeTiny::to_TypeTiny, avg 7µs/call |
239 | |||||
240 | 4 | 22µs | 8 | 51µs | if ( blessed $type and my $method = $type->can( 'type_coercion_map' ) ) { # spent 46µs making 4 calls to Type::Tiny::can, avg 12µs/call
# spent 5µs making 4 calls to Scalar::Util::blessed, avg 1µs/call |
241 | push @{ $self->type_coercion_map }, @{ $method->( $type ) }; | ||||
242 | } | ||||
243 | else { | ||||
244 | 4 | 1µs | my $coercion = shift @args; | ||
245 | 4 | 5µs | 4 | 437µs | _croak "Types must be blessed Type::Tiny objects" # spent 437µs making 4 calls to Types::TypeTiny::is_TypeTiny, avg 109µs/call |
246 | unless Types::TypeTiny::is_TypeTiny( $type ); | ||||
247 | 4 | 5µs | 4 | 317µs | _croak "Coercions must be code references or strings" # spent 317µs making 4 calls to Types::TypeTiny::is_StringLike, avg 79µs/call |
248 | unless Types::TypeTiny::is_StringLike( $coercion ) | ||||
249 | || Types::TypeTiny::is_CodeLike( $coercion ); | ||||
250 | 4 | 8µs | 4 | 6µs | push @{ $self->type_coercion_map }, $type, $coercion; # spent 6µs making 4 calls to Type::Coercion::type_coercion_map, avg 2µs/call |
251 | } | ||||
252 | } #/ while ( @args ) | ||||
253 | |||||
254 | 2 | 3µs | 2 | 4µs | $self->_clear_compiled_coercion; # spent 4µs making 2 calls to Type::Coercion::_clear_compiled_coercion, avg 2µs/call |
255 | 2 | 7µs | return $self; | ||
256 | } #/ sub add_type_coercions | ||||
257 | |||||
258 | # spent 560µs (39+521) within Type::Coercion::_build_compiled_coercion which was called:
# once (39µs+521µs) by Type::Coercion::compiled_coercion at line 95 | ||||
259 | 1 | 0s | my $self = shift; | ||
260 | |||||
261 | 1 | 3µs | 1 | 1µs | my @mishmash = @{ $self->type_coercion_map }; # spent 1µs making 1 call to Type::Coercion::type_coercion_map |
262 | return sub { $_[0] } | ||||
263 | 1 | 5µs | unless @mishmash; | ||
264 | |||||
265 | 1 | 15µs | 4 | 520µs | if ( $self->can_be_inlined ) { # spent 219µs making 1 call to Type::Coercion::inline_coercion
# spent 193µs making 1 call to Eval::TypeTiny::eval_closure
# spent 92µs making 1 call to Type::Coercion::can_be_inlined
# spent 16µs making 1 call to Type::Coercion::__ANON__[Type/Coercion.pm:27] |
266 | return Eval::TypeTiny::eval_closure( | ||||
267 | source => sprintf( 'sub ($) { %s }', $self->inline_coercion( '$_[0]' ) ), | ||||
268 | description => sprintf( "compiled coercion '%s'", $self ), | ||||
269 | ); | ||||
270 | } | ||||
271 | |||||
272 | # These arrays will be closed over. | ||||
273 | my ( @types, @codes ); | ||||
274 | while ( @mishmash ) { | ||||
275 | push @types, shift @mishmash; | ||||
276 | push @codes, shift @mishmash; | ||||
277 | } | ||||
278 | if ( $self->has_type_constraint ) { | ||||
279 | unshift @types, $self->type_constraint; | ||||
280 | unshift @codes, undef; | ||||
281 | } | ||||
282 | |||||
283 | my @sub; | ||||
284 | |||||
285 | for my $i ( 0 .. $#types ) { | ||||
286 | push @sub, | ||||
287 | $types[$i]->can_be_inlined | ||||
288 | ? sprintf( 'if (%s)', $types[$i]->inline_check( '$_[0]' ) ) | ||||
289 | : sprintf( 'if ($checks[%d]->(@_))', $i ); | ||||
290 | push @sub, | ||||
291 | !defined( $codes[$i] ) | ||||
292 | ? sprintf( ' { return $_[0] }' ) | ||||
293 | : Types::TypeTiny::is_StringLike( $codes[$i] ) ? sprintf( | ||||
294 | ' { local $_ = $_[0]; return scalar(%s); }', | ||||
295 | $codes[$i] | ||||
296 | ) | ||||
297 | : sprintf( ' { local $_ = $_[0]; return scalar($codes[%d]->(@_)) }', $i ); | ||||
298 | } #/ for my $i ( 0 .. $#types) | ||||
299 | |||||
300 | push @sub, 'return $_[0];'; | ||||
301 | |||||
302 | return Eval::TypeTiny::eval_closure( | ||||
303 | source => sprintf( 'sub ($) { %s }', join qq[\n], @sub ), | ||||
304 | description => sprintf( "compiled coercion '%s'", $self ), | ||||
305 | environment => { | ||||
306 | '@checks' => [ map $_->compiled_check, @types ], | ||||
307 | '@codes' => \@codes, | ||||
308 | }, | ||||
309 | ); | ||||
310 | } #/ sub _build_compiled_coercion | ||||
311 | |||||
312 | sub can_be_inlined { | ||||
313 | 2 | 1µs | my $self = shift; | ||
314 | |||||
315 | 2 | 2µs | 2 | 3µs | return unless $self->frozen; # spent 3µs making 2 calls to Type::Coercion::frozen, avg 2µs/call |
316 | |||||
317 | return | ||||
318 | 2 | 7µs | 6 | 60µs | if $self->has_type_constraint # spent 34µs making 2 calls to Type::Tiny::can_be_inlined, avg 17µs/call
# spent 19µs making 2 calls to Type::Coercion::has_type_constraint, avg 10µs/call
# spent 7µs making 2 calls to Type::Coercion::type_constraint, avg 4µs/call |
319 | && !$self->type_constraint->can_be_inlined; | ||||
320 | |||||
321 | 2 | 3µs | 2 | 2µs | my @mishmash = @{ $self->type_coercion_map }; # spent 2µs making 2 calls to Type::Coercion::type_coercion_map, avg 1µs/call |
322 | 2 | 2µs | while ( @mishmash ) { | ||
323 | 2 | 3µs | my ( $type, $converter ) = splice( @mishmash, 0, 2 ); | ||
324 | 2 | 4µs | 2 | 23µs | return unless $type->can_be_inlined; # spent 23µs making 2 calls to Type::Tiny::can_be_inlined, avg 12µs/call |
325 | 2 | 4µs | 2 | 44µs | return unless Types::TypeTiny::is_StringLike( $converter ); # spent 44µs making 2 calls to Types::TypeTiny::is_StringLike, avg 22µs/call |
326 | } | ||||
327 | 2 | 7µs | return !!1; | ||
328 | } #/ sub can_be_inlined | ||||
329 | |||||
330 | sub _source_type_union { | ||||
331 | my $self = shift; | ||||
332 | |||||
333 | my @r; | ||||
334 | push @r, $self->type_constraint if $self->has_type_constraint; | ||||
335 | |||||
336 | my @mishmash = @{ $self->type_coercion_map }; | ||||
337 | while ( @mishmash ) { | ||||
338 | my ( $type ) = splice( @mishmash, 0, 2 ); | ||||
339 | push @r, $type; | ||||
340 | } | ||||
341 | |||||
342 | require Type::Tiny::Union; | ||||
343 | return "Type::Tiny::Union"->new( type_constraints => \@r, tmp => 1 ); | ||||
344 | } #/ sub _source_type_union | ||||
345 | |||||
346 | # spent 219µs (45+174) within Type::Coercion::inline_coercion which was called:
# once (45µs+174µs) by Type::Coercion::_build_compiled_coercion at line 265 | ||||
347 | 1 | 1µs | my $self = shift; | ||
348 | 1 | 0s | my $varname = $_[0]; | ||
349 | |||||
350 | 1 | 0s | 1 | 86µs | _croak "This coercion cannot be inlined" unless $self->can_be_inlined; # spent 86µs making 1 call to Type::Coercion::can_be_inlined |
351 | |||||
352 | 1 | 6µs | 1 | 1µs | my @mishmash = @{ $self->type_coercion_map }; # spent 1µs making 1 call to Type::Coercion::type_coercion_map |
353 | 1 | 1µs | return "($varname)" unless @mishmash; | ||
354 | |||||
355 | 1 | 0s | my ( @types, @codes ); | ||
356 | 1 | 1µs | while ( @mishmash ) { | ||
357 | 1 | 1µs | push @types, shift @mishmash; | ||
358 | 1 | 1µs | push @codes, shift @mishmash; | ||
359 | } | ||||
360 | 1 | 2µs | 1 | 7µs | if ( $self->has_type_constraint ) { # spent 7µs making 1 call to Type::Coercion::has_type_constraint |
361 | 1 | 0s | 1 | 2µs | unshift @types, $self->type_constraint; # spent 2µs making 1 call to Type::Coercion::type_constraint |
362 | 1 | 0s | unshift @codes, undef; | ||
363 | } | ||||
364 | |||||
365 | 1 | 0s | my @sub; | ||
366 | |||||
367 | 1 | 3µs | for my $i ( 0 .. $#types ) { | ||
368 | 2 | 6µs | 2 | 78µs | push @sub, sprintf( '(%s) ?', $types[$i]->inline_check( $varname ) ); # spent 78µs making 2 calls to Type::Tiny::inline_check, avg 39µs/call |
369 | 2 | 3µs | push @sub, | ||
370 | ( defined( $codes[$i] ) && ( $varname eq '$_' ) ) | ||||
371 | ? sprintf( 'scalar(do { %s }) :', $codes[$i] ) | ||||
372 | : defined( $codes[$i] ) ? sprintf( | ||||
373 | 'scalar(do { local $_ = %s; %s }) :', $varname, | ||||
374 | $codes[$i] | ||||
375 | ) | ||||
376 | : sprintf( '%s :', $varname ); | ||||
377 | } #/ for my $i ( 0 .. $#types) | ||||
378 | |||||
379 | 1 | 1µs | push @sub, "$varname"; | ||
380 | |||||
381 | 1 | 12µs | "@sub"; | ||
382 | } #/ sub inline_coercion | ||||
383 | |||||
384 | sub _build_moose_coercion { | ||||
385 | my $self = shift; | ||||
386 | |||||
387 | my %options = (); | ||||
388 | $options{type_coercion_map} = | ||||
389 | [ $self->freeze->_codelike_type_coercion_map( 'moose_type' ) ]; | ||||
390 | $options{type_constraint} = $self->type_constraint | ||||
391 | if $self->has_type_constraint; | ||||
392 | |||||
393 | require Moose::Meta::TypeCoercion; | ||||
394 | my $r = "Moose::Meta::TypeCoercion"->new( %options ); | ||||
395 | |||||
396 | return $r; | ||||
397 | } #/ sub _build_moose_coercion | ||||
398 | |||||
399 | sub _codelike_type_coercion_map { | ||||
400 | my $self = shift; | ||||
401 | my $modifier = $_[0]; | ||||
402 | |||||
403 | my @orig = @{ $self->type_coercion_map }; | ||||
404 | my @new; | ||||
405 | |||||
406 | while ( @orig ) { | ||||
407 | my ( $type, $converter ) = splice( @orig, 0, 2 ); | ||||
408 | |||||
409 | push @new, $modifier ? $type->$modifier : $type; | ||||
410 | |||||
411 | if ( Types::TypeTiny::is_CodeLike( $converter ) ) { | ||||
412 | push @new, $converter; | ||||
413 | } | ||||
414 | else { | ||||
415 | push @new, Eval::TypeTiny::eval_closure( | ||||
416 | source => sprintf( 'sub { local $_ = $_[0]; %s }', $converter ), | ||||
417 | description => sprintf( "temporary compiled converter from '%s'", $type ), | ||||
418 | ); | ||||
419 | } | ||||
420 | } #/ while ( @orig ) | ||||
421 | |||||
422 | return @new; | ||||
423 | } #/ sub _codelike_type_coercion_map | ||||
424 | |||||
425 | # spent 11µs (8+3) within Type::Coercion::is_parameterizable which was called 3 times, avg 4µs/call:
# 3 times (8µs+3µs) by Eval::TypeTiny::type_to_coderef at line 149 of Eval/TypeTiny.pm, avg 4µs/call | ||||
426 | 3 | 6µs | 3 | 3µs | shift->has_coercion_generator; # spent 3µs making 3 calls to Type::Coercion::has_coercion_generator, avg 1µs/call |
427 | } | ||||
428 | |||||
429 | sub is_parameterized { | ||||
430 | shift->has_parameters; | ||||
431 | } | ||||
432 | |||||
433 | sub parameterize { | ||||
434 | my $self = shift; | ||||
435 | return $self unless @_; | ||||
436 | $self->is_parameterizable | ||||
437 | or _croak "Constraint '%s' does not accept parameters", "$self"; | ||||
438 | |||||
439 | @_ = map Types::TypeTiny::to_TypeTiny( $_ ), @_; | ||||
440 | |||||
441 | return ref( $self )->new( | ||||
442 | type_constraint => $self->type_constraint, | ||||
443 | type_coercion_map => | ||||
444 | [ $self->coercion_generator->( $self, $self->type_constraint, @_ ) ], | ||||
445 | parameters => \@_, | ||||
446 | frozen => 1, | ||||
447 | parameterized_from => $self, | ||||
448 | ); | ||||
449 | } #/ sub parameterize | ||||
450 | |||||
451 | sub _reparameterize { | ||||
452 | my $self = shift; | ||||
453 | my ( $target_type ) = @_; | ||||
454 | |||||
455 | $self->is_parameterized or return $self; | ||||
456 | my $parent = $self->parameterized_from; | ||||
457 | |||||
458 | return ref( $self )->new( | ||||
459 | type_constraint => $target_type, | ||||
460 | type_coercion_map => [ | ||||
461 | $parent->coercion_generator->( $parent, $target_type, @{ $self->parameters } ) | ||||
462 | ], | ||||
463 | parameters => \@_, | ||||
464 | frozen => 1, | ||||
465 | parameterized_from => $parent, | ||||
466 | ); | ||||
467 | } #/ sub _reparameterize | ||||
468 | |||||
469 | sub isa { | ||||
470 | my $self = shift; | ||||
471 | |||||
472 | if ( $INC{"Moose.pm"} | ||||
473 | and blessed( $self ) | ||||
474 | and $_[0] eq 'Moose::Meta::TypeCoercion' ) | ||||
475 | { | ||||
476 | return !!1; | ||||
477 | } | ||||
478 | |||||
479 | if ( $INC{"Moose.pm"} | ||||
480 | and blessed( $self ) | ||||
481 | and $_[0] =~ /^(Class::MOP|MooseX?)::/ ) | ||||
482 | { | ||||
483 | my $r = $self->moose_coercion->isa( @_ ); | ||||
484 | return $r if $r; | ||||
485 | } | ||||
486 | |||||
487 | $self->SUPER::isa( @_ ); | ||||
488 | } #/ sub isa | ||||
489 | |||||
490 | sub can { | ||||
491 | my $self = shift; | ||||
492 | |||||
493 | my $can = $self->SUPER::can( @_ ); | ||||
494 | return $can if $can; | ||||
495 | |||||
496 | if ( $INC{"Moose.pm"} | ||||
497 | and blessed( $self ) | ||||
498 | and my $method = $self->moose_coercion->can( @_ ) ) | ||||
499 | { | ||||
500 | return sub { $method->( shift->moose_coercion, @_ ) }; | ||||
501 | } | ||||
502 | |||||
503 | return; | ||||
504 | } #/ sub can | ||||
505 | |||||
506 | # spent 9µs (5+4) within Type::Coercion::AUTOLOAD which was called:
# once (5µs+4µs) by Types::Standard::Dict::__coercion_generator at line 267 of Types/Standard/Dict.pm | ||||
507 | 1 | 0s | my $self = shift; | ||
508 | 1 | 7µs | 1 | 4µs | my ( $m ) = ( our $AUTOLOAD =~ /::(\w+)$/ ); # spent 4µs making 1 call to Type::Coercion::CORE:match |
509 | 1 | 3µs | return if $m eq 'DESTROY'; | ||
510 | |||||
511 | if ( $INC{"Moose.pm"} | ||||
512 | and blessed( $self ) | ||||
513 | and my $method = $self->moose_coercion->can( $m ) ) | ||||
514 | { | ||||
515 | return $method->( $self->moose_coercion, @_ ); | ||||
516 | } | ||||
517 | |||||
518 | _croak q[Can't locate object method "%s" via package "%s"], $m, | ||||
519 | ref( $self ) || $self; | ||||
520 | } #/ sub AUTOLOAD | ||||
521 | |||||
522 | # Private Moose method, but Moo uses this... | ||||
523 | sub _compiled_type_coercion { | ||||
524 | my $self = shift; | ||||
525 | if ( @_ ) { | ||||
526 | my $thing = $_[0]; | ||||
527 | if ( blessed( $thing ) and $thing->isa( "Type::Coercion" ) ) { | ||||
528 | $self->add_type_coercions( @{ $thing->type_coercion_map } ); | ||||
529 | } | ||||
530 | elsif ( Types::TypeTiny::is_CodeLike( $thing ) ) { | ||||
531 | require Types::Standard; | ||||
532 | $self->add_type_coercions( Types::Standard::Any(), $thing ); | ||||
533 | } | ||||
534 | } #/ if ( @_ ) | ||||
535 | $self->compiled_coercion; | ||||
536 | } #/ sub _compiled_type_coercion | ||||
537 | |||||
538 | 1 | 0s | *compile_type_coercion = \&compiled_coercion; | ||
539 | sub meta { _croak( "Not really a Moose::Meta::TypeCoercion. Sorry!" ) } | ||||
540 | |||||
541 | 1 | 9µs | 1; | ||
542 | |||||
543 | __END__ | ||||
# spent 15µs within Type::Coercion::CORE:match which was called 5 times, avg 3µs/call:
# 3 times (10µs+0s) by Type::Coercion::new at line 69, avg 3µs/call
# once (4µs+0s) by Type::Coercion::AUTOLOAD at line 508
# once (1µs+0s) by Type::Coercion::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Coercion.pm:27] at line 24 |