| Filename | /Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard/Map.pm |
| Statements | Executed 47 statements in 1.60ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 3 | 1 | 1 | 101µs | 816µs | Types::Standard::Map::__ANON__[:87] |
| 1 | 1 | 1 | 86µs | 86µs | Types::Standard::Map::BEGIN@5 |
| 1 | 1 | 1 | 20µs | 2.39ms | Types::Standard::Map::__constraint_generator |
| 1 | 1 | 1 | 11µs | 36µs | Types::Standard::Map::__inline_generator |
| 1 | 1 | 1 | 10µs | 35µs | Types::Standard::Map::BEGIN@24 |
| 1 | 1 | 1 | 8µs | 11µs | Types::Standard::Map::BEGIN@6 |
| 1 | 1 | 1 | 7µs | 49µs | Types::Standard::Map::BEGIN@7 |
| 1 | 1 | 1 | 4µs | 4µs | Types::Standard::Map::BEGIN@16 |
| 1 | 1 | 1 | 3µs | 3µs | Types::Standard::Map::BEGIN@18 |
| 1 | 1 | 1 | 2µs | 2µs | Types::Standard::Map::BEGIN@17 |
| 1 | 1 | 1 | 2µs | 2µs | Types::Standard::Map::BEGIN@9 |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::__ANON__[:168] |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::__ANON__[:186] |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::__ANON__[:200] |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::__ANON__[:214] |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::__ANON__[:56] |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::__coercion_generator |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::__deep_explanation |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::__hashref_allows_key |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::__hashref_allows_value |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::_croak |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::my_hashref_allows_key |
| 0 | 0 | 0 | 0s | 0s | Types::Standard::Map::my_hashref_allows_value |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | # INTERNAL MODULE: guts for Map type from Types::Standard. | ||||
| 2 | |||||
| 3 | package Types::Standard::Map; | ||||
| 4 | |||||
| 5 | 2 | 63µs | 1 | 86µs | # spent 86µs within Types::Standard::Map::BEGIN@5 which was called:
# once (86µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:190] at line 5 # spent 86µs making 1 call to Types::Standard::Map::BEGIN@5 |
| 6 | 2 | 29µs | 2 | 14µs | # spent 11µs (8+3) within Types::Standard::Map::BEGIN@6 which was called:
# once (8µs+3µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:190] at line 6 # spent 11µs making 1 call to Types::Standard::Map::BEGIN@6
# spent 3µs making 1 call to strict::import |
| 7 | 2 | 44µs | 2 | 91µs | # spent 49µs (7+42) within Types::Standard::Map::BEGIN@7 which was called:
# once (7µs+42µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:190] at line 7 # spent 49µs making 1 call to Types::Standard::Map::BEGIN@7
# spent 42µs making 1 call to warnings::import |
| 8 | |||||
| 9 | # spent 2µs within Types::Standard::Map::BEGIN@9 which was called:
# once (2µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:190] at line 12 | ||||
| 10 | 1 | 0s | $Types::Standard::Map::AUTHORITY = 'cpan:TOBYINK'; | ||
| 11 | 1 | 4µs | $Types::Standard::Map::VERSION = '2.000001'; | ||
| 12 | 1 | 32µs | 1 | 2µs | } # spent 2µs making 1 call to Types::Standard::Map::BEGIN@9 |
| 13 | |||||
| 14 | 1 | 2µs | $Types::Standard::Map::VERSION =~ tr/_//d; | ||
| 15 | |||||
| 16 | 2 | 24µs | 1 | 4µs | # spent 4µs within Types::Standard::Map::BEGIN@16 which was called:
# once (4µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:190] at line 16 # spent 4µs making 1 call to Types::Standard::Map::BEGIN@16 |
| 17 | 2 | 14µs | 1 | 2µs | # spent 2µs within Types::Standard::Map::BEGIN@17 which was called:
# once (2µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:190] at line 17 # spent 2µs making 1 call to Types::Standard::Map::BEGIN@17 |
| 18 | 2 | 101µs | 1 | 3µs | # spent 3µs within Types::Standard::Map::BEGIN@18 which was called:
# once (3µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:190] at line 18 # spent 3µs making 1 call to Types::Standard::Map::BEGIN@18 |
| 19 | |||||
| 20 | sub _croak ($;@) { require Error::TypeTiny; goto \&Error::TypeTiny::croak } | ||||
| 21 | |||||
| 22 | 1 | 5µs | 1 | 16µs | my $meta = Types::Standard->meta; # spent 16µs making 1 call to Type::Library::meta |
| 23 | |||||
| 24 | 2 | 1.21ms | 2 | 60µs | # spent 35µs (10+25) within Types::Standard::Map::BEGIN@24 which was called:
# once (10µs+25µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:190] at line 24 # spent 35µs making 1 call to Types::Standard::Map::BEGIN@24
# spent 25µs making 1 call to warnings::unimport |
| 25 | |||||
| 26 | # spent 2.39ms (20µs+2.37) within Types::Standard::Map::__constraint_generator which was called:
# once (20µs+2.37ms) by Type::Tiny::parameterize at line 1044 of Type/Tiny.pm | ||||
| 27 | 1 | 0s | return $meta->get_type( 'Map' ) unless @_; | ||
| 28 | |||||
| 29 | 1 | 1µs | my ( $keys, $values ) = @_; | ||
| 30 | 1 | 1µs | 1 | 29µs | Types::TypeTiny::is_TypeTiny( $keys ) # spent 29µs making 1 call to Types::TypeTiny::is_TypeTiny |
| 31 | or _croak( | ||||
| 32 | "First parameter to Map[`k,`v] expected to be a type constraint; got $keys" ); | ||||
| 33 | 1 | 2µs | 1 | 14µs | Types::TypeTiny::is_TypeTiny( $values ) # spent 14µs making 1 call to Types::TypeTiny::is_TypeTiny |
| 34 | or _croak( | ||||
| 35 | "Second parameter to Map[`k,`v] expected to be a type constraint; got $values" | ||||
| 36 | ); | ||||
| 37 | |||||
| 38 | 1 | 0s | my @xsub; | ||
| 39 | if ( Type::Tiny::_USE_XS ) { | ||||
| 40 | my @known = map { | ||||
| 41 | my $known = Type::Tiny::XS::is_known( $_->compiled_check ); | ||||
| 42 | defined( $known ) ? $known : (); | ||||
| 43 | } ( $keys, $values ); | ||||
| 44 | |||||
| 45 | if ( @known == 2 ) { | ||||
| 46 | my $xsub = Type::Tiny::XS::get_coderef_for( sprintf "Map[%s,%s]", @known ); | ||||
| 47 | push @xsub, $xsub if $xsub; | ||||
| 48 | } | ||||
| 49 | } #/ if ( Type::Tiny::_USE_XS) | ||||
| 50 | |||||
| 51 | sub { | ||||
| 52 | my $hash = shift; | ||||
| 53 | $keys->check( $_ ) || return for keys %$hash; | ||||
| 54 | $values->check( $_ ) || return for values %$hash; | ||||
| 55 | return !!1; | ||||
| 56 | 1 | 6µs | }, @xsub; | ||
| 57 | } #/ sub __constraint_generator | ||||
| 58 | |||||
| 59 | # spent 36µs (11+25) within Types::Standard::Map::__inline_generator which was called:
# once (11µs+25µs) by Type::Tiny::parameterize at line 1057 of Type/Tiny.pm | ||||
| 60 | 1 | 1µs | my ( $k, $v ) = @_; | ||
| 61 | 1 | 3µs | 2 | 25µs | return unless $k->can_be_inlined && $v->can_be_inlined; # spent 25µs making 2 calls to Type::Tiny::can_be_inlined, avg 12µs/call |
| 62 | |||||
| 63 | 1 | 1µs | my $xsubname; | ||
| 64 | if ( Type::Tiny::_USE_XS ) { | ||||
| 65 | my @known = map { | ||||
| 66 | my $known = Type::Tiny::XS::is_known( $_->compiled_check ); | ||||
| 67 | defined( $known ) ? $known : (); | ||||
| 68 | } ( $k, $v ); | ||||
| 69 | |||||
| 70 | if ( @known == 2 ) { | ||||
| 71 | $xsubname = Type::Tiny::XS::get_subname_for( sprintf "Map[%s,%s]", @known ); | ||||
| 72 | } | ||||
| 73 | } #/ if ( Type::Tiny::_USE_XS) | ||||
| 74 | |||||
| 75 | # spent 816µs (101+715) within Types::Standard::Map::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard/Map.pm:87] which was called 3 times, avg 272µs/call:
# 3 times (101µs+715µs) by Type::Tiny::inline_check at line 895 of Type/Tiny.pm, avg 272µs/call | ||||
| 76 | 3 | 2µs | my $h = $_[1]; | ||
| 77 | 3 | 1µs | return "$xsubname\($h\)" if $xsubname && !$Type::Tiny::AvoidCallbacks; | ||
| 78 | 3 | 13µs | 6 | 12µs | my $p = Types::Standard::HashRef->inline_check( $h ); # spent 12µs making 3 calls to Types::Standard::HashRef, avg 4µs/call
# spent 275µs making 3 calls to Type::Tiny::inline_check, avg 92µs/call, recursion: max depth 1, sum of overlapping time 275µs |
| 79 | 3 | 5µs | 3 | 0s | my $k_check = $k->inline_check( '$k' ); # spent 321µs making 3 calls to Type::Tiny::inline_check, avg 107µs/call, recursion: max depth 1, sum of overlapping time 321µs |
| 80 | 3 | 5µs | 3 | 0s | my $v_check = $v->inline_check( '$v' ); # spent 107µs making 3 calls to Type::Tiny::inline_check, avg 36µs/call, recursion: max depth 1, sum of overlapping time 107µs |
| 81 | 3 | 19µs | "$p and do { " | ||
| 82 | . "my \$ok = 1; " | ||||
| 83 | . "for my \$v (values \%{$h}) { " | ||||
| 84 | . "(\$ok = 0, last) unless $v_check " . "}; " | ||||
| 85 | . "for my \$k (keys \%{$h}) { " | ||||
| 86 | . "(\$ok = 0, last) unless $k_check " . "}; " . "\$ok " . "}"; | ||||
| 87 | 1 | 5µs | }; | ||
| 88 | } #/ sub __inline_generator | ||||
| 89 | |||||
| 90 | sub __deep_explanation { | ||||
| 91 | require B; | ||||
| 92 | my ( $type, $value, $varname ) = @_; | ||||
| 93 | my ( $kparam, $vparam ) = @{ $type->parameters }; | ||||
| 94 | |||||
| 95 | for my $k ( sort keys %$value ) { | ||||
| 96 | unless ( $kparam->check( $k ) ) { | ||||
| 97 | return [ | ||||
| 98 | sprintf( '"%s" constrains each key in the hash with "%s"', $type, $kparam ), | ||||
| 99 | @{ | ||||
| 100 | $kparam->validate_explain( | ||||
| 101 | $k, sprintf( 'key %s->{%s}', $varname, B::perlstring( $k ) ) | ||||
| 102 | ) | ||||
| 103 | }, | ||||
| 104 | ]; | ||||
| 105 | } #/ unless ( $kparam->check( $k...)) | ||||
| 106 | |||||
| 107 | unless ( $vparam->check( $value->{$k} ) ) { | ||||
| 108 | return [ | ||||
| 109 | sprintf( '"%s" constrains each value in the hash with "%s"', $type, $vparam ), | ||||
| 110 | @{ | ||||
| 111 | $vparam->validate_explain( | ||||
| 112 | $value->{$k}, sprintf( '%s->{%s}', $varname, B::perlstring( $k ) ) | ||||
| 113 | ) | ||||
| 114 | }, | ||||
| 115 | ]; | ||||
| 116 | } #/ unless ( $vparam->check( $value...)) | ||||
| 117 | } #/ for my $k ( sort keys %$value) | ||||
| 118 | |||||
| 119 | # This should never happen... | ||||
| 120 | return; # uncoverable statement | ||||
| 121 | } #/ sub __deep_explanation | ||||
| 122 | |||||
| 123 | sub __coercion_generator { | ||||
| 124 | my ( $parent, $child, $kparam, $vparam ) = @_; | ||||
| 125 | return unless $kparam->has_coercion || $vparam->has_coercion; | ||||
| 126 | |||||
| 127 | my $kcoercable_item = | ||||
| 128 | $kparam->has_coercion | ||||
| 129 | ? $kparam->coercion->_source_type_union | ||||
| 130 | : $kparam; | ||||
| 131 | my $vcoercable_item = | ||||
| 132 | $vparam->has_coercion | ||||
| 133 | ? $vparam->coercion->_source_type_union | ||||
| 134 | : $vparam; | ||||
| 135 | my $C = "Type::Coercion"->new( type_constraint => $child ); | ||||
| 136 | |||||
| 137 | if ( ( !$kparam->has_coercion or $kparam->coercion->can_be_inlined ) | ||||
| 138 | and ( !$vparam->has_coercion or $vparam->coercion->can_be_inlined ) | ||||
| 139 | and $kcoercable_item->can_be_inlined | ||||
| 140 | and $vcoercable_item->can_be_inlined ) | ||||
| 141 | { | ||||
| 142 | $C->add_type_coercions( | ||||
| 143 | $parent => Types::Standard::Stringable { | ||||
| 144 | my @code; | ||||
| 145 | push @code, 'do { my ($orig, $return_orig, %new) = ($_, 0);'; | ||||
| 146 | push @code, 'for (keys %$orig) {'; | ||||
| 147 | push @code, | ||||
| 148 | sprintf( | ||||
| 149 | '++$return_orig && last unless (%s);', | ||||
| 150 | $kcoercable_item->inline_check( '$_' ) | ||||
| 151 | ); | ||||
| 152 | push @code, | ||||
| 153 | sprintf( | ||||
| 154 | '++$return_orig && last unless (%s);', | ||||
| 155 | $vcoercable_item->inline_check( '$orig->{$_}' ) | ||||
| 156 | ); | ||||
| 157 | push @code, sprintf( | ||||
| 158 | '$new{(%s)} = (%s);', | ||||
| 159 | $kparam->has_coercion ? $kparam->coercion->inline_coercion( '$_' ) : '$_', | ||||
| 160 | $vparam->has_coercion | ||||
| 161 | ? $vparam->coercion->inline_coercion( '$orig->{$_}' ) | ||||
| 162 | : '$orig->{$_}', | ||||
| 163 | ); | ||||
| 164 | push @code, '}'; | ||||
| 165 | push @code, '$return_orig ? $orig : \\%new'; | ||||
| 166 | push @code, '}'; | ||||
| 167 | "@code"; | ||||
| 168 | } | ||||
| 169 | ); | ||||
| 170 | } #/ if ( ( !$kparam->has_coercion...)) | ||||
| 171 | else { | ||||
| 172 | $C->add_type_coercions( | ||||
| 173 | $parent => sub { | ||||
| 174 | my $value = @_ ? $_[0] : $_; | ||||
| 175 | my %new; | ||||
| 176 | for my $k ( keys %$value ) { | ||||
| 177 | return $value | ||||
| 178 | unless $kcoercable_item->check( $k ) | ||||
| 179 | && $vcoercable_item->check( $value->{$k} ); | ||||
| 180 | $new{ $kparam->has_coercion ? $kparam->coerce( $k ) : $k } = | ||||
| 181 | $vparam->has_coercion | ||||
| 182 | ? $vparam->coerce( $value->{$k} ) | ||||
| 183 | : $value->{$k}; | ||||
| 184 | } | ||||
| 185 | return \%new; | ||||
| 186 | }, | ||||
| 187 | ); | ||||
| 188 | } #/ else [ if ( ( !$kparam->has_coercion...))] | ||||
| 189 | |||||
| 190 | return $C; | ||||
| 191 | } #/ sub __coercion_generator | ||||
| 192 | |||||
| 193 | sub __hashref_allows_key { | ||||
| 194 | my $self = shift; | ||||
| 195 | my ( $key ) = @_; | ||||
| 196 | |||||
| 197 | return Types::Standard::is_Str( $key ) if $self == Types::Standard::Map(); | ||||
| 198 | |||||
| 199 | my $map = $self->find_parent( | ||||
| 200 | sub { $_->has_parent && $_->parent == Types::Standard::Map() } ); | ||||
| 201 | my ( $kcheck, $vcheck ) = @{ $map->parameters }; | ||||
| 202 | |||||
| 203 | ( $kcheck or Types::Standard::Any() )->check( $key ); | ||||
| 204 | } #/ sub __hashref_allows_key | ||||
| 205 | |||||
| 206 | sub __hashref_allows_value { | ||||
| 207 | my $self = shift; | ||||
| 208 | my ( $key, $value ) = @_; | ||||
| 209 | |||||
| 210 | return !!0 unless $self->my_hashref_allows_key( $key ); | ||||
| 211 | return !!1 if $self == Types::Standard::Map(); | ||||
| 212 | |||||
| 213 | my $map = $self->find_parent( | ||||
| 214 | sub { $_->has_parent && $_->parent == Types::Standard::Map() } ); | ||||
| 215 | my ( $kcheck, $vcheck ) = @{ $map->parameters }; | ||||
| 216 | |||||
| 217 | ( $kcheck or Types::Standard::Any() )->check( $key ) | ||||
| 218 | and ( $vcheck or Types::Standard::Any() )->check( $value ); | ||||
| 219 | } #/ sub __hashref_allows_value | ||||
| 220 | |||||
| 221 | 1 | 5µs | 1; |