Filename | /Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Coercion.pm |
Statements | Executed 1368 statements in 4.79ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
58 | 3 | 3 | 842µs | 9.41ms | new | Type::Coercion::
58 | 1 | 1 | 403µs | 7.90ms | _preserve_type_constraint | Type::Coercion::
61 | 2 | 2 | 220µs | 286µs | is_anon | Type::Coercion::
56 | 4 | 3 | 124µs | 124µs | freeze | Type::Coercion::
2 | 2 | 2 | 96µs | 781µs | add_type_coercions | Type::Coercion::
56 | 5 | 2 | 85µs | 85µs | type_coercion_map | Type::Coercion::
70 | 4 | 2 | 72µs | 72µs | name | Type::Coercion::
1 | 1 | 1 | 52µs | 185µs | inline_coercion | Type::Coercion::
2 | 2 | 1 | 40µs | 155µs | can_be_inlined | Type::Coercion::
1 | 1 | 1 | 32µs | 32µs | BEGIN@3 | Type::Coercion::
52 | 2 | 1 | 31µs | 31µs | __ANON__[:28] | Type::Coercion::
1 | 1 | 1 | 24µs | 537µs | _build_compiled_coercion | Type::Coercion::
5 | 3 | 1 | 20µs | 20µs | CORE:match (opcode) | Type::Coercion::
3 | 1 | 1 | 18µs | 22µs | qualified_name | Type::Coercion::
6 | 3 | 1 | 15µs | 21µs | type_constraint | Type::Coercion::
1 | 1 | 1 | 13µs | 16µs | __ANON__[:27] | Type::Coercion::
3 | 1 | 1 | 11µs | 14µs | is_parameterizable | Type::Coercion::
3 | 2 | 1 | 9µs | 22µs | has_type_constraint | Type::Coercion::
6 | 4 | 3 | 8µs | 8µs | frozen | Type::Coercion::
1 | 1 | 1 | 6µs | 8µs | BEGIN@4 | Type::Coercion::
1 | 1 | 1 | 5µs | 30µs | BEGIN@15 | Type::Coercion::
1 | 1 | 1 | 5µs | 35µs | BEGIN@5 | Type::Coercion::
1 | 1 | 1 | 5µs | 542µs | compiled_coercion | Type::Coercion::
1 | 1 | 1 | 3µs | 9µs | AUTOLOAD | Type::Coercion::
1 | 1 | 1 | 3µs | 3µs | BEGIN@14 | 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@16 | Type::Coercion::
2 | 1 | 1 | 2µs | 2µs | _clear_compiled_coercion | Type::Coercion::
1 | 1 | 1 | 2µs | 2µs | display_name | Type::Coercion::
3 | 1 | 1 | 2µs | 2µs | has_library | 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 | 45µs | 1 | 32µs | # spent 32µs within Type::Coercion::BEGIN@3 which was called:
# once (32µs+0s) by Type::Tiny::_build_coercion at line 3 # spent 32µs making 1 call to Type::Coercion::BEGIN@3 |
4 | 2 | 18µs | 2 | 10µs | # spent 8µs (6+2) within Type::Coercion::BEGIN@4 which was called:
# once (6µs+2µs) by Type::Tiny::_build_coercion at line 4 # spent 8µs making 1 call to Type::Coercion::BEGIN@4
# spent 2µs making 1 call to strict::import |
5 | 2 | 28µs | 2 | 65µs | # spent 35µs (5+30) within Type::Coercion::BEGIN@5 which was called:
# once (5µs+30µs) by Type::Tiny::_build_coercion at line 5 # spent 35µs making 1 call to Type::Coercion::BEGIN@5
# spent 30µ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 | 3µs | $Type::Coercion::VERSION = '2.000001'; | ||
10 | 1 | 23µs | 1 | 3µs | } # spent 3µs making 1 call to Type::Coercion::BEGIN@7 |
11 | |||||
12 | 1 | 1µs | $Type::Coercion::VERSION =~ tr/_//d; | ||
13 | |||||
14 | 2 | 13µs | 1 | 3µs | # spent 3µs within Type::Coercion::BEGIN@14 which was called:
# once (3µs+0s) by Type::Tiny::_build_coercion at line 14 # spent 3µs making 1 call to Type::Coercion::BEGIN@14 |
15 | 2 | 17µs | 2 | 55µs | # spent 30µs (5+25) within Type::Coercion::BEGIN@15 which was called:
# once (5µs+25µs) by Type::Tiny::_build_coercion at line 15 # spent 30µs making 1 call to Type::Coercion::BEGIN@15
# spent 25µs making 1 call to Exporter::import |
16 | 2 | 2.20ms | 1 | 2µs | # spent 2µs within Type::Coercion::BEGIN@16 which was called:
# once (2µs+0s) by Type::Tiny::_build_coercion at line 16 # spent 2µs making 1 call to Type::Coercion::BEGIN@16 |
17 | |||||
18 | sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak } | ||||
19 | |||||
20 | 1 | 1µ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 | 140µs | # spent 31µs within Type::Coercion::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Type/Coercion.pm:28] which was called 52 times, avg 596ns/call:
# 48 times (29µs+0s) by Type::Tiny::has_coercion at line 472 of Type/Tiny.pm, avg 604ns/call
# 4 times (2µs+0s) by Type::Tiny::coercion at line 439 of Type/Tiny.pm, avg 500ns/call | ||
29 | 1 | 6µs | 1 | 22µs | q(&{}) => "_overload_coderef", # spent 22µ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 | 2µs | 1 | 7µs | ) if Type::Tiny::SUPPORT_SMARTMATCH(); # spent 7µ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.41ms (842µs+8.57) within Type::Coercion::new which was called 58 times, avg 162µs/call:
# 54 times (741µs+8.26ms) by Type::Tiny::_build_coercion at line 503 of Type/Tiny.pm, avg 167µs/call
# 3 times (88µs+294µs) by Type::Library::add_coercion at line 274 of Type/Library.pm, avg 127µs/call
# once (13µs+15µs) by Types::Standard::Dict::__coercion_generator at line 251 of Types/Standard/Dict.pm | ||||
53 | 58 | 14µs | my $class = shift; | ||
54 | 58 | 92µs | my %params = ( @_ == 1 ) ? %{ $_[0] } : @_; | ||
55 | |||||
56 | 58 | 55µs | $params{name} = '__ANON__' unless exists( $params{name} ); | ||
57 | 58 | 32µs | my $C = delete( $params{type_coercion_map} ) || []; | ||
58 | 58 | 20µs | my $F = delete( $params{frozen} ); | ||
59 | |||||
60 | 58 | 31µs | my $self = bless \%params, $class; | ||
61 | 58 | 18µs | 1 | 204µs | $self->add_type_coercions( @$C ) if @$C; # spent 204µs making 1 call to Type::Coercion::add_type_coercions |
62 | 58 | 76µs | 58 | 7.90ms | $self->_preserve_type_constraint; # spent 7.90ms making 58 calls to Type::Coercion::_preserve_type_constraint, avg 136µs/call |
63 | 58 | 285µs | 58 | 172µs | Scalar::Util::weaken( $self->{type_constraint} ); # break ref cycle # spent 172µs making 58 calls to Scalar::Util::weaken, avg 3µs/call |
64 | 58 | 13µs | $self->{frozen} = $F if $F; | ||
65 | |||||
66 | 58 | 71µs | 58 | 279µs | unless ( $self->is_anon ) { # spent 279µs making 58 calls to Type::Coercion::is_anon, avg 5µs/call |
67 | |||||
68 | # First try a fast ASCII-only expression, but fall back to Unicode | ||||
69 | 3 | 24µs | 6 | 15µs | $self->name =~ /^_{0,2}[A-Z][A-Za-z0-9_]+$/sm # spent 13µs making 3 calls to Type::Coercion::CORE:match, avg 4µ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 | 127µ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 | 133µs | # spent 72µs within Type::Coercion::name which was called 70 times, avg 1µs/call:
# 61 times (66µs+0s) by Type::Coercion::is_anon at line 176, 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::qualified_name at line 171, 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 21µs (15+6) within Type::Coercion::type_constraint which was called 6 times, avg 4µs/call:
# 3 times (9µs+4µs) by Type::Coercion::has_type_constraint at line 103, avg 4µs/call
# 2 times (4µs+1µs) by Type::Coercion::can_be_inlined at line 318, avg 2µs/call
# once (2µs+1µs) by Type::Coercion::inline_coercion at line 361 | ||||
89 | 6 | 17µ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 | 142µs | # spent 85µs within Type::Coercion::type_coercion_map which was called 56 times, avg 2µs/call:
# 48 times (77µs+0s) by Type::Tiny::has_coercion at line 472 of Type/Tiny.pm, avg 2µs/call
# 4 times (5µs+0s) by Type::Coercion::add_type_coercions at line 250, avg 1µs/call
# 2 times (1µs+0s) by Type::Coercion::can_be_inlined at line 321, avg 500ns/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 542µs (5+537) within Type::Coercion::compiled_coercion which was called:
# once (5µs+537µs) by Type::Tiny::exportables at line 1220 of Type/Tiny.pm | ||||
95 | 1 | 6µs | 1 | 537µs | $_[0]{compiled_coercion} ||= $_[0]->_build_compiled_coercion; # spent 537µs making 1 call to Type::Coercion::_build_compiled_coercion |
96 | } | ||||
97 | 6 | 21µs | # spent 8µs within Type::Coercion::frozen which was called 6 times, avg 1µs/call:
# 2 times (5µs+0s) by Type::Coercion::add_type_coercions at line 234, avg 2µs/call
# 2 times (1µs+0s) by Type::Coercion::can_be_inlined at line 315, avg 500ns/call
# once (2µs+0s) by Type::Library::make_immutable at line 319 of Type/Library.pm
# once (0s+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 | 6µs | # spent 2µs within Type::Coercion::has_library which was called 3 times, avg 667ns/call:
# 3 times (2µs+0s) by Type::Coercion::qualified_name at line 167, avg 667ns/call | ||
103 | 3 | 9µs | 3 | 13µs | sub has_type_constraint { defined $_[0]->type_constraint } # sic # spent 13µs making 3 calls to Type::Coercion::type_constraint, avg 4µ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.90ms (403µs+7.50) within Type::Coercion::_preserve_type_constraint which was called 58 times, avg 136µs/call:
# 58 times (403µs+7.50ms) by Type::Coercion::new at line 62, avg 136µs/call | ||||
108 | 58 | 8µs | my $self = shift; | ||
109 | $self->{_compiled_type_constraint_check} = | ||||
110 | $self->{type_constraint}->compiled_check | ||||
111 | 58 | 366µs | 116 | 7.50ms | if $self->{type_constraint}; # spent 7.41ms making 58 calls to Type::Tiny::compiled_check, avg 128µs/call
# spent 89µs making 58 calls to Type::Tiny::__ANON__[Type/Tiny.pm:101], avg 2µs/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 22µs (18+4) within Type::Coercion::qualified_name which was called 3 times, avg 7µs/call:
# 3 times (18µs+4µs) by Eval::TypeTiny::type_to_coderef at line 169 of Eval/TypeTiny.pm, avg 7µs/call | ||||
165 | 3 | 1µs | my $self = shift; | ||
166 | |||||
167 | 3 | 5µs | 3 | 2µs | if ( $self->has_library and not $self->is_anon ) { # spent 2µs making 3 calls to Type::Coercion::has_library, avg 667ns/call |
168 | return sprintf( "%s::%s", $self->library, $self->name ); | ||||
169 | } | ||||
170 | |||||
171 | 3 | 7µs | 3 | 2µs | return $self->name; # spent 2µs making 3 calls to Type::Coercion::name, avg 667ns/call |
172 | } | ||||
173 | |||||
174 | # spent 286µs (220+66) within Type::Coercion::is_anon which was called 61 times, avg 5µs/call:
# 58 times (214µs+65µs) by Type::Coercion::new at line 66, avg 5µs/call
# 3 times (6µs+1000ns) by Type::Library::add_coercion at line 279 of Type/Library.pm, avg 2µs/call | ||||
175 | 61 | 35µs | my $self = shift; | ||
176 | 61 | 282µs | 61 | 66µs | $self->name eq "__ANON__"; # spent 66µs making 61 calls to Type::Coercion::name, avg 1µs/call |
177 | } | ||||
178 | |||||
179 | # spent 2µs within Type::Coercion::_clear_compiled_coercion which was called 2 times, avg 1µs/call:
# 2 times (2µs+0s) by Type::Coercion::add_type_coercions at line 254, avg 1µs/call | ||||
180 | 2 | 0s | delete $_[0]{_overload_coderef}; | ||
181 | 2 | 5µs | delete $_[0]{compiled_coercion}; | ||
182 | } | ||||
183 | |||||
184 | 112 | 177µs | # spent 124µs within Type::Coercion::freeze which was called 56 times, avg 2µs/call:
# 37 times (94µs+0s) by Type::Library::make_immutable at line 318 of Type/Library.pm, avg 3µs/call
# 14 times (24µs+0s) by Type::Tiny::parameterize at line 1082 of Type/Tiny.pm, avg 2µs/call
# 3 times (5µ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 2µ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 781µs (96+685) within Type::Coercion::add_type_coercions which was called 2 times, avg 390µs/call:
# once (29µs+548µs) by JSON::Schema::Modern::BEGIN@31 at line 234 of Types/Standard.pm
# once (67µs+137µs) by Type::Coercion::new at line 61 | ||||
231 | 2 | 0s | my $self = shift; | ||
232 | 2 | 2µs | my @args = @_; | ||
233 | |||||
234 | 2 | 4µs | 2 | 5µs | _croak "Attempt to add coercion code to a Type::Coercion which has been frozen" # spent 5µs making 2 calls to Type::Coercion::frozen, avg 2µs/call |
235 | if $self->frozen; | ||||
236 | |||||
237 | 2 | 2µs | while ( @args ) { | ||
238 | 4 | 8µs | 4 | 33µs | my $type = Types::TypeTiny::to_TypeTiny( shift @args ); # spent 33µs making 4 calls to Types::TypeTiny::to_TypeTiny, avg 8µs/call |
239 | |||||
240 | 4 | 38µs | 8 | 53µ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 7µs making 4 calls to Scalar::Util::blessed, avg 2µs/call |
241 | push @{ $self->type_coercion_map }, @{ $method->( $type ) }; | ||||
242 | } | ||||
243 | else { | ||||
244 | 4 | 2µs | my $coercion = shift @args; | ||
245 | 4 | 7µs | 4 | 349µs | _croak "Types must be blessed Type::Tiny objects" # spent 349µs making 4 calls to Types::TypeTiny::is_TypeTiny, avg 87µs/call |
246 | unless Types::TypeTiny::is_TypeTiny( $type ); | ||||
247 | 4 | 3µs | 4 | 238µs | _croak "Coercions must be code references or strings" # spent 238µs making 4 calls to Types::TypeTiny::is_StringLike, avg 60µs/call |
248 | unless Types::TypeTiny::is_StringLike( $coercion ) | ||||
249 | || Types::TypeTiny::is_CodeLike( $coercion ); | ||||
250 | 4 | 9µs | 4 | 5µs | push @{ $self->type_coercion_map }, $type, $coercion; # spent 5µs making 4 calls to Type::Coercion::type_coercion_map, avg 1µs/call |
251 | } | ||||
252 | } #/ while ( @args ) | ||||
253 | |||||
254 | 2 | 3µs | 2 | 2µs | $self->_clear_compiled_coercion; # spent 2µs making 2 calls to Type::Coercion::_clear_compiled_coercion, avg 1µs/call |
255 | 2 | 6µs | return $self; | ||
256 | } #/ sub add_type_coercions | ||||
257 | |||||
258 | # spent 537µs (24+513) within Type::Coercion::_build_compiled_coercion which was called:
# once (24µs+513µs) by Type::Coercion::compiled_coercion at line 95 | ||||
259 | 1 | 1µs | my $self = shift; | ||
260 | |||||
261 | 1 | 2µ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 | 1µs | unless @mishmash; | ||
264 | |||||
265 | 1 | 15µs | 4 | 512µs | if ( $self->can_be_inlined ) { # spent 210µs making 1 call to Eval::TypeTiny::eval_closure
# spent 185µs making 1 call to Type::Coercion::inline_coercion
# spent 101µ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 | 1µs | return unless $self->frozen; # spent 1µs making 2 calls to Type::Coercion::frozen, avg 500ns/call |
316 | |||||
317 | return | ||||
318 | 2 | 7µs | 6 | 54µs | if $self->has_type_constraint # spent 34µs making 2 calls to Type::Tiny::can_be_inlined, avg 17µs/call
# spent 15µs making 2 calls to Type::Coercion::has_type_constraint, avg 8µs/call
# spent 5µs making 2 calls to Type::Coercion::type_constraint, avg 2µs/call |
319 | && !$self->type_constraint->can_be_inlined; | ||||
320 | |||||
321 | 2 | 2µs | 2 | 1µs | my @mishmash = @{ $self->type_coercion_map }; # spent 1µs making 2 calls to Type::Coercion::type_coercion_map, avg 500ns/call |
322 | 2 | 2µs | while ( @mishmash ) { | ||
323 | 2 | 3µs | my ( $type, $converter ) = splice( @mishmash, 0, 2 ); | ||
324 | 2 | 1µs | 2 | 16µs | return unless $type->can_be_inlined; # spent 16µs making 2 calls to Type::Tiny::can_be_inlined, avg 8µs/call |
325 | 2 | 2µs | 2 | 43µs | return unless Types::TypeTiny::is_StringLike( $converter ); # spent 43µs making 2 calls to Types::TypeTiny::is_StringLike, avg 22µs/call |
326 | } | ||||
327 | 2 | 6µ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 185µs (52+133) within Type::Coercion::inline_coercion which was called:
# once (52µs+133µs) by Type::Coercion::_build_compiled_coercion at line 265 | ||||
347 | 1 | 1µs | my $self = shift; | ||
348 | 1 | 1µs | my $varname = $_[0]; | ||
349 | |||||
350 | 1 | 2µs | 1 | 54µs | _croak "This coercion cannot be inlined" unless $self->can_be_inlined; # spent 54µs making 1 call to Type::Coercion::can_be_inlined |
351 | |||||
352 | 1 | 2µs | 1 | 1µs | my @mishmash = @{ $self->type_coercion_map }; # spent 1µs making 1 call to Type::Coercion::type_coercion_map |
353 | 1 | 0s | return "($varname)" unless @mishmash; | ||
354 | |||||
355 | 1 | 1µs | my ( @types, @codes ); | ||
356 | 1 | 1µs | while ( @mishmash ) { | ||
357 | 1 | 1µs | push @types, shift @mishmash; | ||
358 | 1 | 0s | push @codes, shift @mishmash; | ||
359 | } | ||||
360 | 1 | 3µs | 1 | 7µs | if ( $self->has_type_constraint ) { # spent 7µs making 1 call to Type::Coercion::has_type_constraint |
361 | 1 | 2µs | 1 | 3µs | unshift @types, $self->type_constraint; # spent 3µs making 1 call to Type::Coercion::type_constraint |
362 | 1 | 1µs | unshift @codes, undef; | ||
363 | } | ||||
364 | |||||
365 | 1 | 0s | my @sub; | ||
366 | |||||
367 | 1 | 2µs | for my $i ( 0 .. $#types ) { | ||
368 | 2 | 8µs | 2 | 68µs | push @sub, sprintf( '(%s) ?', $types[$i]->inline_check( $varname ) ); # spent 68µs making 2 calls to Type::Tiny::inline_check, avg 34µs/call |
369 | 2 | 4µ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 | 6µ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 14µs (11+3) within Type::Coercion::is_parameterizable which was called 3 times, avg 5µs/call:
# 3 times (11µs+3µs) by Eval::TypeTiny::type_to_coderef at line 149 of Eval/TypeTiny.pm, avg 5µs/call | ||||
426 | 3 | 9µ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 (3+6) within Type::Coercion::AUTOLOAD which was called:
# once (3µs+6µs) by Types::Standard::Dict::__coercion_generator at line 267 of Types/Standard/Dict.pm | ||||
507 | 1 | 0s | my $self = shift; | ||
508 | 1 | 8µs | 1 | 6µs | my ( $m ) = ( our $AUTOLOAD =~ /::(\w+)$/ ); # spent 6µ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 | 1µs | *compile_type_coercion = \&compiled_coercion; | ||
539 | sub meta { _croak( "Not really a Moose::Meta::TypeCoercion. Sorry!" ) } | ||||
540 | |||||
541 | 1 | 7µs | 1; | ||
542 | |||||
543 | __END__ | ||||
# spent 20µs within Type::Coercion::CORE:match which was called 5 times, avg 4µs/call:
# 3 times (13µs+0s) by Type::Coercion::new at line 69, avg 4µs/call
# once (6µ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 |