| Filename | /Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/TypeTiny.pm |
| Statements | Executed 11012 statements in 13.0ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 3550 | 6 | 4 | 4.80ms | 5.78ms | Types::TypeTiny::to_TypeTiny |
| 3470 | 1 | 1 | 981µs | 981µs | Types::TypeTiny::CORE:match (opcode) |
| 343 | 1 | 1 | 234µs | 263µs | Types::TypeTiny::TypeTiny |
| 1 | 1 | 1 | 112µs | 112µs | Types::TypeTiny::BEGIN@14 |
| 38 | 1 | 1 | 40µs | 60µs | Types::TypeTiny::StringLike |
| 1 | 1 | 1 | 20µs | 20µs | Types::TypeTiny::BEGIN@3 |
| 1 | 1 | 1 | 8µs | 37µs | Types::TypeTiny::BEGIN@623 |
| 1 | 1 | 1 | 7µs | 27µs | Types::TypeTiny::BEGIN@5 |
| 1 | 1 | 1 | 6µs | 21µs | Types::TypeTiny::BEGIN@45 |
| 1 | 1 | 1 | 6µs | 11µs | Types::TypeTiny::BEGIN@68 |
| 1 | 1 | 1 | 6µs | 8µs | Types::TypeTiny::BEGIN@98 |
| 5 | 3 | 1 | 6µs | 6µs | Types::TypeTiny::type_names |
| 1 | 1 | 1 | 5µs | 28µs | Types::TypeTiny::BEGIN@12 |
| 1 | 1 | 1 | 5µs | 7µs | Types::TypeTiny::BEGIN@4 |
| 1 | 1 | 1 | 5µs | 13µs | Types::TypeTiny::BEGIN@630 |
| 1 | 1 | 1 | 4µs | 6µs | Types::TypeTiny::BEGIN@114 |
| 1 | 1 | 1 | 4µs | 13µs | Types::TypeTiny::BEGIN@69 |
| 1 | 1 | 1 | 4µs | 6µs | Types::TypeTiny::__ANON__[:174] |
| 1 | 1 | 1 | 3µs | 3µs | Types::TypeTiny::__ANON__[:413] |
| 1 | 1 | 1 | 2µs | 4µs | Types::TypeTiny::BEGIN@124 |
| 1 | 1 | 1 | 2µs | 2µs | Types::TypeTiny::_get_check_overload_sub |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::ArrayLike |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::CodeLike |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::HashLike |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_ForeignTypeConstraint |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromCodeRef |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromGeneric |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromMoose |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromMoose_baseclass |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromMoose_class |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromMoose_ducktype |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromMoose_enum |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromMoose_parameterizable |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromMoose_role |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromMoose_union |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromMouse |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_TypeTinyFromValidationClass |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:137] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:171] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:175] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:190] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:208] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:211] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:212] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:222] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:223] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:235] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:236] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:252] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:255] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:270] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:290] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:293] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:294] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:304] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:305] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:317] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:318] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:334] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:337] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:352] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:375] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:378] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:379] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:395] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:409] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:414] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:420] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:432] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:508] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:531] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:583] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:607] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:616] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:624] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:626] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:631] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:633] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:647] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:659] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:662] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:667] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:676] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:690] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:691] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:696] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:707] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:725] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:730] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::__ANON__[:745] |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_check_overload |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_is_ForeignTypeConstraint |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_mkall |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::_reinstall_subs |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::coercion_names |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::get_coercion |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::get_type |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::has_coercion |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::has_type |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::import |
| 0 | 0 | 0 | 0s | 0s | Types::TypeTiny::meta |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | package Types::TypeTiny; | ||||
| 2 | |||||
| 3 | 2 | 30µs | 1 | 20µs | # spent 20µs within Types::TypeTiny::BEGIN@3 which was called:
# once (20µs+0s) by Type::Tiny::BEGIN@21 at line 3 # spent 20µs making 1 call to Types::TypeTiny::BEGIN@3 |
| 4 | 2 | 16µs | 2 | 9µs | # spent 7µs (5+2) within Types::TypeTiny::BEGIN@4 which was called:
# once (5µs+2µs) by Type::Tiny::BEGIN@21 at line 4 # spent 7µs making 1 call to Types::TypeTiny::BEGIN@4
# spent 2µs making 1 call to strict::import |
| 5 | 2 | 41µs | 2 | 47µs | # spent 27µs (7+20) within Types::TypeTiny::BEGIN@5 which was called:
# once (7µs+20µs) by Type::Tiny::BEGIN@21 at line 5 # spent 27µs making 1 call to Types::TypeTiny::BEGIN@5
# spent 20µs making 1 call to warnings::import |
| 6 | |||||
| 7 | 1 | 1µs | our $AUTHORITY = 'cpan:TOBYINK'; | ||
| 8 | 1 | 0s | our $VERSION = '2.000001'; | ||
| 9 | |||||
| 10 | 1 | 1µs | $VERSION =~ tr/_//d; | ||
| 11 | |||||
| 12 | 2 | 56µs | 2 | 51µs | # spent 28µs (5+23) within Types::TypeTiny::BEGIN@12 which was called:
# once (5µs+23µs) by Type::Tiny::BEGIN@21 at line 12 # spent 28µs making 1 call to Types::TypeTiny::BEGIN@12
# spent 23µs making 1 call to Exporter::import |
| 13 | |||||
| 14 | # spent 112µs within Types::TypeTiny::BEGIN@14 which was called:
# once (112µs+0s) by Type::Tiny::BEGIN@21 at line 22 | ||||
| 15 | *__XS = eval { | ||||
| 16 | 1 | 112µs | require Type::Tiny::XS; | ||
| 17 | 'Type::Tiny::XS'->VERSION( '0.022' ); | ||||
| 18 | 1; | ||||
| 19 | } | ||||
| 20 | ? sub () { !!1 } | ||||
| 21 | 1 | 0s | : sub () { !!0 }; | ||
| 22 | 1 | 78µs | 1 | 112µs | } # spent 112µs making 1 call to Types::TypeTiny::BEGIN@14 |
| 23 | |||||
| 24 | our @EXPORT_OK = ( | ||||
| 25 | 1 | 10µs | 1 | 3µs | map( @{ [ $_, "is_$_", "assert_$_" ] }, __PACKAGE__->type_names ), # spent 3µs making 1 call to Types::TypeTiny::type_names |
| 26 | qw/to_TypeTiny/ | ||||
| 27 | ); | ||||
| 28 | 1 | 11µs | 3 | 2µs | our %EXPORT_TAGS = ( # spent 2µs making 3 calls to Types::TypeTiny::type_names, avg 667ns/call |
| 29 | types => [ __PACKAGE__->type_names ], | ||||
| 30 | is => [ map "is_$_", __PACKAGE__->type_names ], | ||||
| 31 | assert => [ map "assert_$_", __PACKAGE__->type_names ], | ||||
| 32 | ); | ||||
| 33 | |||||
| 34 | 1 | 1µs | my %cache; | ||
| 35 | |||||
| 36 | # This `import` method is designed to avoid loading Exporter::Tiny. | ||||
| 37 | # This is so that if you stick to only using the purely OO parts of | ||||
| 38 | # Type::Tiny, you can skip loading the exporter. | ||||
| 39 | # | ||||
| 40 | sub import { | ||||
| 41 | |||||
| 42 | # If this sub succeeds, it will replace itself. | ||||
| 43 | # uncoverable subroutine | ||||
| 44 | return unless @_ > 1; # uncoverable statement | ||||
| 45 | 2 | 103µs | 2 | 36µs | # spent 21µs (6+15) within Types::TypeTiny::BEGIN@45 which was called:
# once (6µs+15µs) by Type::Tiny::BEGIN@21 at line 45 # spent 21µs making 1 call to Types::TypeTiny::BEGIN@45
# spent 15µs making 1 call to warnings::unimport |
| 46 | our @ISA = qw( Exporter::Tiny ); # uncoverable statement | ||||
| 47 | require Exporter::Tiny; # uncoverable statement | ||||
| 48 | my $next = \&Exporter::Tiny::import; # uncoverable statement | ||||
| 49 | *import = $next; # uncoverable statement | ||||
| 50 | my $class = shift; # uncoverable statement | ||||
| 51 | my $opts = { ref( $_[0] ) ? %{ +shift } : () }; # uncoverable statement | ||||
| 52 | $opts->{into} ||= scalar( caller ); # uncoverable statement | ||||
| 53 | _mkall(); # uncoverable statement | ||||
| 54 | return $class->$next( $opts, @_ ); # uncoverable statement | ||||
| 55 | } #/ sub import | ||||
| 56 | |||||
| 57 | 1 | 1µs | 1 | 1µs | for ( __PACKAGE__->type_names ) { # uncoverable statement # spent 1µs making 1 call to Types::TypeTiny::type_names |
| 58 | 6 | 236µs | eval qq{ # uncoverable statement # spent 698µs executing statements in string eval # includes 861µs spent executing 343 calls to 2 subs defined therein. # spent 75µs executing statements in string eval # includes 94µs spent executing 38 calls to 2 subs defined therein. | ||
| 59 | sub is_$_ { $_()->check(shift) } # uncoverable statement | ||||
| 60 | sub assert_$_ { $_()->assert_return(shift) } # uncoverable statement | ||||
| 61 | }; # uncoverable statement | ||||
| 62 | } # uncoverable statement | ||||
| 63 | |||||
| 64 | sub _reinstall_subs { | ||||
| 65 | |||||
| 66 | # uncoverable subroutine | ||||
| 67 | my $type = shift; # uncoverable statement | ||||
| 68 | 2 | 23µs | 2 | 16µs | # spent 11µs (6+5) within Types::TypeTiny::BEGIN@68 which was called:
# once (6µs+5µs) by Type::Tiny::BEGIN@21 at line 68 # spent 11µs making 1 call to Types::TypeTiny::BEGIN@68
# spent 5µs making 1 call to strict::unimport |
| 69 | 2 | 111µs | 2 | 22µs | # spent 13µs (4+9) within Types::TypeTiny::BEGIN@69 which was called:
# once (4µs+9µs) by Type::Tiny::BEGIN@21 at line 69 # spent 13µs making 1 call to Types::TypeTiny::BEGIN@69
# spent 9µs making 1 call to warnings::unimport |
| 70 | *{ 'is_' . $type->name } = $type->compiled_check; # uncoverable statement | ||||
| 71 | *{ 'assert_' . $type->name } = \&$type; # uncoverable statement | ||||
| 72 | $type; # uncoverable statement | ||||
| 73 | } # uncoverable statement | ||||
| 74 | |||||
| 75 | sub _mkall { | ||||
| 76 | |||||
| 77 | # uncoverable subroutine | ||||
| 78 | return unless $INC{'Type/Tiny.pm'}; # uncoverable statement | ||||
| 79 | __PACKAGE__->get_type( $_ ) for __PACKAGE__->type_names; # uncoverable statement | ||||
| 80 | } # uncoverable statement | ||||
| 81 | |||||
| 82 | sub meta { | ||||
| 83 | return $_[0]; | ||||
| 84 | } | ||||
| 85 | |||||
| 86 | sub type_names { | ||||
| 87 | 5 | 14µs | qw( CodeLike StringLike TypeTiny HashLike ArrayLike _ForeignTypeConstraint ); | ||
| 88 | } | ||||
| 89 | |||||
| 90 | sub has_type { | ||||
| 91 | my %has = map +( $_ => 1 ), shift->type_names; | ||||
| 92 | !!$has{ $_[0] }; | ||||
| 93 | } | ||||
| 94 | |||||
| 95 | sub get_type { | ||||
| 96 | my $self = shift; | ||||
| 97 | return unless $self->has_type( @_ ); | ||||
| 98 | 2 | 65µs | 2 | 10µs | # spent 8µs (6+2) within Types::TypeTiny::BEGIN@98 which was called:
# once (6µs+2µs) by Type::Tiny::BEGIN@21 at line 98 # spent 8µs making 1 call to Types::TypeTiny::BEGIN@98
# spent 2µs making 1 call to strict::unimport |
| 99 | &{ $_[0] }(); | ||||
| 100 | } | ||||
| 101 | |||||
| 102 | sub coercion_names { | ||||
| 103 | qw(); | ||||
| 104 | } | ||||
| 105 | |||||
| 106 | sub has_coercion { | ||||
| 107 | my %has = map +( $_ => 1 ), shift->coercion_names; | ||||
| 108 | !!$has{ $_[0] }; | ||||
| 109 | } | ||||
| 110 | |||||
| 111 | sub get_coercion { | ||||
| 112 | my $self = shift; | ||||
| 113 | return unless $self->has_coercion( @_ ); | ||||
| 114 | 2 | 47µs | 2 | 8µs | # spent 6µs (4+2) within Types::TypeTiny::BEGIN@114 which was called:
# once (4µs+2µs) by Type::Tiny::BEGIN@21 at line 114 # spent 6µs making 1 call to Types::TypeTiny::BEGIN@114
# spent 2µs making 1 call to strict::unimport |
| 115 | &{ $_[0] }(); # uncoverable statement | ||||
| 116 | } | ||||
| 117 | |||||
| 118 | 1 | 1µs | my ( $__get_linear_isa_dfs, $tried_mro ); | ||
| 119 | $__get_linear_isa_dfs = sub { | ||||
| 120 | if ( !$tried_mro && eval { require mro } ) { | ||||
| 121 | $__get_linear_isa_dfs = \&mro::get_linear_isa; | ||||
| 122 | goto $__get_linear_isa_dfs; | ||||
| 123 | } | ||||
| 124 | 2 | 2.65ms | 2 | 6µs | # spent 4µs (2+2) within Types::TypeTiny::BEGIN@124 which was called:
# once (2µs+2µs) by Type::Tiny::BEGIN@21 at line 124 # spent 4µs making 1 call to Types::TypeTiny::BEGIN@124
# spent 2µs making 1 call to strict::unimport |
| 125 | my $classname = shift; | ||||
| 126 | my @lin = ( $classname ); | ||||
| 127 | my %stored; | ||||
| 128 | foreach my $parent ( @{"$classname\::ISA"} ) { | ||||
| 129 | my $plin = $__get_linear_isa_dfs->( $parent ); | ||||
| 130 | foreach ( @$plin ) { | ||||
| 131 | next if exists $stored{$_}; | ||||
| 132 | push( @lin, $_ ); | ||||
| 133 | $stored{$_} = 1; | ||||
| 134 | } | ||||
| 135 | } | ||||
| 136 | return \@lin; | ||||
| 137 | 1 | 2µs | }; | ||
| 138 | |||||
| 139 | sub _check_overload { | ||||
| 140 | my $package = shift; | ||||
| 141 | if ( ref $package ) { | ||||
| 142 | $package = blessed( $package ); | ||||
| 143 | return !!0 if !defined $package; | ||||
| 144 | } | ||||
| 145 | my $op = shift; | ||||
| 146 | my $mro = $__get_linear_isa_dfs->( $package ); | ||||
| 147 | foreach my $p ( @$mro ) { | ||||
| 148 | my $fqmeth = $p . q{::(} . $op; | ||||
| 149 | return !!1 if defined &{$fqmeth}; | ||||
| 150 | } | ||||
| 151 | !!0; | ||||
| 152 | } #/ sub _check_overload | ||||
| 153 | |||||
| 154 | # spent 2µs within Types::TypeTiny::_get_check_overload_sub which was called:
# once (2µs+0s) by Types::TypeTiny::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/TypeTiny.pm:174] at line 173 | ||||
| 155 | 1 | 1µs | if ( $Type::Tiny::AvoidCallbacks ) { | ||
| 156 | return | ||||
| 157 | '(sub { require overload; overload::Overloaded(ref $_[0] or $_[0]) and overload::Method((ref $_[0] or $_[0]), $_[1]) })->'; | ||||
| 158 | } | ||||
| 159 | 1 | 3µs | return 'Types::TypeTiny::_check_overload'; | ||
| 160 | } | ||||
| 161 | |||||
| 162 | # spent 60µs (40+20) within Types::TypeTiny::StringLike which was called 38 times, avg 2µs/call:
# 38 times (40µs+20µs) by Types::TypeTiny::is_StringLike at line 2 of (eval 39)[Types/TypeTiny.pm:58], avg 2µs/call | ||||
| 163 | 38 | 44µs | return $cache{StringLike} if defined $cache{StringLike}; | ||
| 164 | 1 | 1µs | require Type::Tiny; | ||
| 165 | my %common = ( | ||||
| 166 | name => "StringLike", | ||||
| 167 | library => __PACKAGE__, | ||||
| 168 | constraint => sub { | ||||
| 169 | defined( $_ ) && !ref( $_ ) | ||||
| 170 | or blessed( $_ ) && _check_overload( $_, q[""] ); | ||||
| 171 | }, | ||||
| 172 | # spent 6µs (4+2) within Types::TypeTiny::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/TypeTiny.pm:174] which was called:
# once (4µs+2µs) by Type::Tiny::inline_check at line 895 of Type/Tiny.pm | ||||
| 173 | 1 | 3µs | 1 | 2µs | qq/defined($_[1]) && !ref($_[1]) or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[""])/; # spent 2µs making 1 call to Types::TypeTiny::_get_check_overload_sub |
| 174 | }, | ||||
| 175 | type_default => sub { return '' }, | ||||
| 176 | 1 | 4µs | ); | ||
| 177 | 1 | 7µs | if ( __XS ) { | ||
| 178 | my $xsub = Type::Tiny::XS::get_coderef_for( 'StringLike' ); | ||||
| 179 | my $xsubname = Type::Tiny::XS::get_subname_for( 'StringLike' ); | ||||
| 180 | my $inlined = $common{inlined}; | ||||
| 181 | $cache{StringLike} = "Type::Tiny"->new( | ||||
| 182 | %common, | ||||
| 183 | compiled_type_constraint => $xsub, | ||||
| 184 | inlined => sub { | ||||
| 185 | |||||
| 186 | # uncoverable subroutine | ||||
| 187 | ( $Type::Tiny::AvoidCallbacks or not $xsubname ) | ||||
| 188 | ? goto( $inlined ) | ||||
| 189 | : qq/$xsubname($_[1])/ # uncoverable statement | ||||
| 190 | }, | ||||
| 191 | ); | ||||
| 192 | _reinstall_subs $cache{StringLike}; | ||||
| 193 | } #/ if ( __XS ) | ||||
| 194 | else { | ||||
| 195 | 1 | 2µs | 1 | 20µs | $cache{StringLike} = "Type::Tiny"->new( %common ); # spent 20µs making 1 call to Type::Tiny::new |
| 196 | } | ||||
| 197 | } #/ sub StringLike | ||||
| 198 | |||||
| 199 | sub HashLike (;@) { | ||||
| 200 | return $cache{HashLike} if defined( $cache{HashLike} ) && !@_; | ||||
| 201 | require Type::Tiny; | ||||
| 202 | my %common = ( | ||||
| 203 | name => "HashLike", | ||||
| 204 | library => __PACKAGE__, | ||||
| 205 | constraint => sub { | ||||
| 206 | ref( $_ ) eq q[HASH] | ||||
| 207 | or blessed( $_ ) && _check_overload( $_, q[%{}] ); | ||||
| 208 | }, | ||||
| 209 | inlined => sub { | ||||
| 210 | qq/ref($_[1]) eq q[HASH] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\%{}])/; | ||||
| 211 | }, | ||||
| 212 | type_default => sub { return {} }, | ||||
| 213 | constraint_generator => sub { | ||||
| 214 | my $param = TypeTiny()->assert_coerce( shift ); | ||||
| 215 | my $check = $param->compiled_check; | ||||
| 216 | sub { | ||||
| 217 | my %hash = %$_; | ||||
| 218 | for my $key ( sort keys %hash ) { | ||||
| 219 | $check->( $hash{$key} ) or return 0; | ||||
| 220 | } | ||||
| 221 | return 1; | ||||
| 222 | }; | ||||
| 223 | }, | ||||
| 224 | inline_generator => sub { | ||||
| 225 | my $param = TypeTiny()->assert_coerce( shift ); | ||||
| 226 | return unless $param->can_be_inlined; | ||||
| 227 | sub { | ||||
| 228 | my $var = pop; | ||||
| 229 | my $code = sprintf( | ||||
| 230 | 'do { my $ok=1; my %%h = %%{%s}; for my $k (sort keys %%h) { ($ok=0,next) unless (%s) }; $ok }', | ||||
| 231 | $var, | ||||
| 232 | $param->inline_check( '$h{$k}' ), | ||||
| 233 | ); | ||||
| 234 | return ( undef, $code ); | ||||
| 235 | }; | ||||
| 236 | }, | ||||
| 237 | coercion_generator => sub { | ||||
| 238 | my ( $parent, $child, $param ) = @_; | ||||
| 239 | return unless $param->has_coercion; | ||||
| 240 | my $coercible = $param->coercion->_source_type_union->compiled_check; | ||||
| 241 | my $C = "Type::Coercion"->new( type_constraint => $child ); | ||||
| 242 | $C->add_type_coercions( | ||||
| 243 | $parent => sub { | ||||
| 244 | my $origref = @_ ? $_[0] : $_; | ||||
| 245 | my %orig = %$origref; | ||||
| 246 | my %new; | ||||
| 247 | for my $k ( sort keys %orig ) { | ||||
| 248 | return $origref unless $coercible->( $orig{$k} ); | ||||
| 249 | $new{$k} = $param->coerce( $orig{$k} ); | ||||
| 250 | } | ||||
| 251 | \%new; | ||||
| 252 | }, | ||||
| 253 | ); | ||||
| 254 | return $C; | ||||
| 255 | }, | ||||
| 256 | ); | ||||
| 257 | if ( __XS ) { | ||||
| 258 | my $xsub = Type::Tiny::XS::get_coderef_for( 'HashLike' ); | ||||
| 259 | my $xsubname = Type::Tiny::XS::get_subname_for( 'HashLike' ); | ||||
| 260 | my $inlined = $common{inlined}; | ||||
| 261 | $cache{HashLike} = "Type::Tiny"->new( | ||||
| 262 | %common, | ||||
| 263 | compiled_type_constraint => $xsub, | ||||
| 264 | inlined => sub { | ||||
| 265 | |||||
| 266 | # uncoverable subroutine | ||||
| 267 | ( $Type::Tiny::AvoidCallbacks or not $xsubname ) | ||||
| 268 | ? goto( $inlined ) | ||||
| 269 | : qq/$xsubname($_[1])/ # uncoverable statement | ||||
| 270 | }, | ||||
| 271 | ); | ||||
| 272 | _reinstall_subs $cache{HashLike}; | ||||
| 273 | } #/ if ( __XS ) | ||||
| 274 | else { | ||||
| 275 | $cache{HashLike} = "Type::Tiny"->new( %common ); | ||||
| 276 | } | ||||
| 277 | |||||
| 278 | @_ ? $cache{HashLike}->parameterize( @{ $_[0] } ) : $cache{HashLike}; | ||||
| 279 | } #/ sub HashLike (;@) | ||||
| 280 | |||||
| 281 | sub ArrayLike (;@) { | ||||
| 282 | return $cache{ArrayLike} if defined( $cache{ArrayLike} ) && !@_; | ||||
| 283 | require Type::Tiny; | ||||
| 284 | my %common = ( | ||||
| 285 | name => "ArrayLike", | ||||
| 286 | library => __PACKAGE__, | ||||
| 287 | constraint => sub { | ||||
| 288 | ref( $_ ) eq q[ARRAY] | ||||
| 289 | or blessed( $_ ) && _check_overload( $_, q[@{}] ); | ||||
| 290 | }, | ||||
| 291 | inlined => sub { | ||||
| 292 | qq/ref($_[1]) eq q[ARRAY] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\@{}])/; | ||||
| 293 | }, | ||||
| 294 | type_default => sub { return [] }, | ||||
| 295 | constraint_generator => sub { | ||||
| 296 | my $param = TypeTiny()->assert_coerce( shift ); | ||||
| 297 | my $check = $param->compiled_check; | ||||
| 298 | sub { | ||||
| 299 | my @arr = @$_; | ||||
| 300 | for my $val ( @arr ) { | ||||
| 301 | $check->( $val ) or return 0; | ||||
| 302 | } | ||||
| 303 | return 1; | ||||
| 304 | }; | ||||
| 305 | }, | ||||
| 306 | inline_generator => sub { | ||||
| 307 | my $param = TypeTiny()->assert_coerce( shift ); | ||||
| 308 | return unless $param->can_be_inlined; | ||||
| 309 | sub { | ||||
| 310 | my $var = pop; | ||||
| 311 | my $code = sprintf( | ||||
| 312 | 'do { my $ok=1; for my $v (@{%s}) { ($ok=0,next) unless (%s) }; $ok }', | ||||
| 313 | $var, | ||||
| 314 | $param->inline_check( '$v' ), | ||||
| 315 | ); | ||||
| 316 | return ( undef, $code ); | ||||
| 317 | }; | ||||
| 318 | }, | ||||
| 319 | coercion_generator => sub { | ||||
| 320 | my ( $parent, $child, $param ) = @_; | ||||
| 321 | return unless $param->has_coercion; | ||||
| 322 | my $coercible = $param->coercion->_source_type_union->compiled_check; | ||||
| 323 | my $C = "Type::Coercion"->new( type_constraint => $child ); | ||||
| 324 | $C->add_type_coercions( | ||||
| 325 | $parent => sub { | ||||
| 326 | my $origref = @_ ? $_[0] : $_; | ||||
| 327 | my @orig = @$origref; | ||||
| 328 | my @new; | ||||
| 329 | for my $v ( @orig ) { | ||||
| 330 | return $origref unless $coercible->( $v ); | ||||
| 331 | push @new, $param->coerce( $v ); | ||||
| 332 | } | ||||
| 333 | \@new; | ||||
| 334 | }, | ||||
| 335 | ); | ||||
| 336 | return $C; | ||||
| 337 | }, | ||||
| 338 | ); | ||||
| 339 | if ( __XS ) { | ||||
| 340 | my $xsub = Type::Tiny::XS::get_coderef_for( 'ArrayLike' ); | ||||
| 341 | my $xsubname = Type::Tiny::XS::get_subname_for( 'ArrayLike' ); | ||||
| 342 | my $inlined = $common{inlined}; | ||||
| 343 | $cache{ArrayLike} = "Type::Tiny"->new( | ||||
| 344 | %common, | ||||
| 345 | compiled_type_constraint => $xsub, | ||||
| 346 | inlined => sub { | ||||
| 347 | |||||
| 348 | # uncoverable subroutine | ||||
| 349 | ( $Type::Tiny::AvoidCallbacks or not $xsubname ) | ||||
| 350 | ? goto( $inlined ) | ||||
| 351 | : qq/$xsubname($_[1])/ # uncoverable statement | ||||
| 352 | }, | ||||
| 353 | ); | ||||
| 354 | _reinstall_subs $cache{ArrayLike}; | ||||
| 355 | } #/ if ( __XS ) | ||||
| 356 | else { | ||||
| 357 | $cache{ArrayLike} = "Type::Tiny"->new( %common ); | ||||
| 358 | } | ||||
| 359 | |||||
| 360 | @_ ? $cache{ArrayLike}->parameterize( @{ $_[0] } ) : $cache{ArrayLike}; | ||||
| 361 | } #/ sub ArrayLike (;@) | ||||
| 362 | |||||
| 363 | 1 | 2µs | if ( $] ge '5.014' ) { | ||
| 364 | 1 | 4µs | 2 | 18µs | &Scalar::Util::set_prototype( $_, ';$' ) for \&HashLike, \&ArrayLike; # spent 18µs making 2 calls to Scalar::Util::set_prototype, avg 9µs/call |
| 365 | } | ||||
| 366 | |||||
| 367 | sub CodeLike () { | ||||
| 368 | return $cache{CodeLike} if $cache{CodeLike}; | ||||
| 369 | require Type::Tiny; | ||||
| 370 | my %common = ( | ||||
| 371 | name => "CodeLike", | ||||
| 372 | constraint => sub { | ||||
| 373 | ref( $_ ) eq q[CODE] | ||||
| 374 | or blessed( $_ ) && _check_overload( $_, q[&{}] ); | ||||
| 375 | }, | ||||
| 376 | inlined => sub { | ||||
| 377 | qq/ref($_[1]) eq q[CODE] or Scalar::Util::blessed($_[1]) && ${\ +_get_check_overload_sub() }($_[1], q[\&{}])/; | ||||
| 378 | }, | ||||
| 379 | type_default => sub { return sub {} }, | ||||
| 380 | library => __PACKAGE__, | ||||
| 381 | ); | ||||
| 382 | if ( __XS ) { | ||||
| 383 | my $xsub = Type::Tiny::XS::get_coderef_for( 'CodeLike' ); | ||||
| 384 | my $xsubname = Type::Tiny::XS::get_subname_for( 'CodeLike' ); | ||||
| 385 | my $inlined = $common{inlined}; | ||||
| 386 | $cache{CodeLike} = "Type::Tiny"->new( | ||||
| 387 | %common, | ||||
| 388 | compiled_type_constraint => $xsub, | ||||
| 389 | inlined => sub { | ||||
| 390 | |||||
| 391 | # uncoverable subroutine | ||||
| 392 | ( $Type::Tiny::AvoidCallbacks or not $xsubname ) | ||||
| 393 | ? goto( $inlined ) | ||||
| 394 | : qq/$xsubname($_[1])/ # uncoverable statement | ||||
| 395 | }, | ||||
| 396 | ); | ||||
| 397 | _reinstall_subs $cache{CodeLike}; | ||||
| 398 | } #/ if ( __XS ) | ||||
| 399 | else { | ||||
| 400 | $cache{CodeLike} = "Type::Tiny"->new( %common ); | ||||
| 401 | } | ||||
| 402 | } #/ sub CodeLike | ||||
| 403 | |||||
| 404 | # spent 263µs (234+29) within Types::TypeTiny::TypeTiny which was called 343 times, avg 767ns/call:
# 343 times (234µs+29µs) by Types::TypeTiny::is_TypeTiny at line 2 of (eval 40)[Types/TypeTiny.pm:58], avg 767ns/call | ||||
| 405 | 343 | 436µs | return $cache{TypeTiny} if defined $cache{TypeTiny}; | ||
| 406 | 1 | 1µs | require Type::Tiny; | ||
| 407 | $cache{TypeTiny} = "Type::Tiny"->new( | ||||
| 408 | name => "TypeTiny", | ||||
| 409 | constraint => sub { blessed( $_ ) && $_->isa( q[Type::Tiny] ) }, | ||||
| 410 | # spent 3µs within Types::TypeTiny::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/TypeTiny.pm:413] which was called:
# once (3µs+0s) by Type::Tiny::inline_check at line 895 of Type/Tiny.pm | ||||
| 411 | 1 | 1µs | my $var = $_[1]; | ||
| 412 | 1 | 3µs | "Scalar::Util::blessed($var) && $var\->isa(q[Type::Tiny])"; | ||
| 413 | }, | ||||
| 414 | type_default => sub { require Types::Standard; return Types::Standard::Any() }, | ||||
| 415 | library => __PACKAGE__, | ||||
| 416 | _build_coercion => sub { | ||||
| 417 | my $c = shift; | ||||
| 418 | $c->add_type_coercions( _ForeignTypeConstraint(), \&to_TypeTiny ); | ||||
| 419 | $c->freeze; | ||||
| 420 | }, | ||||
| 421 | 1 | 7µs | 1 | 29µs | ); # spent 29µs making 1 call to Type::Tiny::new |
| 422 | } #/ sub TypeTiny | ||||
| 423 | |||||
| 424 | sub _ForeignTypeConstraint () { | ||||
| 425 | return $cache{_ForeignTypeConstraint} if defined $cache{_ForeignTypeConstraint}; | ||||
| 426 | require Type::Tiny; | ||||
| 427 | $cache{_ForeignTypeConstraint} = "Type::Tiny"->new( | ||||
| 428 | name => "_ForeignTypeConstraint", | ||||
| 429 | constraint => \&_is_ForeignTypeConstraint, | ||||
| 430 | inlined => sub { | ||||
| 431 | qq/ref($_[1]) && do { require Types::TypeTiny; Types::TypeTiny::_is_ForeignTypeConstraint($_[1]) }/; | ||||
| 432 | }, | ||||
| 433 | library => __PACKAGE__, | ||||
| 434 | ); | ||||
| 435 | } #/ sub _ForeignTypeConstraint | ||||
| 436 | |||||
| 437 | 1 | 0s | my %ttt_cache; | ||
| 438 | |||||
| 439 | sub _is_ForeignTypeConstraint { | ||||
| 440 | my $t = @_ ? $_[0] : $_; | ||||
| 441 | return !!1 if ref $t eq 'CODE'; | ||||
| 442 | if ( my $class = blessed $t ) { | ||||
| 443 | return !!0 if $class->isa( "Type::Tiny" ); | ||||
| 444 | return !!1 if $class->isa( "Moose::Meta::TypeConstraint" ); | ||||
| 445 | return !!1 if $class->isa( "MooseX::Types::TypeDecorator" ); | ||||
| 446 | return !!1 if $class->isa( "Validation::Class::Simple" ); | ||||
| 447 | return !!1 if $class->isa( "Validation::Class" ); | ||||
| 448 | return !!1 if $t->can( "check" ); | ||||
| 449 | } | ||||
| 450 | !!0; | ||||
| 451 | } #/ sub _is_ForeignTypeConstraint | ||||
| 452 | |||||
| 453 | # spent 5.78ms (4.80+981µs) within Types::TypeTiny::to_TypeTiny which was called 3550 times, avg 2µs/call:
# 3382 times (4.55ms+937µs) by Type::Tiny::_loose_to_TypeTiny at line 427 of Type/Tiny.pm, avg 2µs/call
# 159 times (232µs+37µs) by Type::Tiny::parameterize at line 1031 of Type/Tiny.pm, avg 2µs/call
# 4 times (12µs+4µs) by Type::Coercion::add_type_coercions at line 238 of Type/Coercion.pm, avg 4µs/call
# 2 times (7µs+2µs) by Type::Tiny::Union::new at line 63 of Type/Tiny/Union.pm, avg 4µs/call
# 2 times (1µs+1µs) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:737] at line 716 of Types/Standard.pm, avg 1µs/call
# once (2µs+0s) by Types::Standard::__ANON__[/Users/ether/.perlbrew/libs/36.0@std/lib/perl5/Types/Standard.pm:678] at line 672 of Types/Standard.pm | ||||
| 454 | 3550 | 435µs | my $t = @_ ? $_[0] : $_; | ||
| 455 | |||||
| 456 | 3550 | 549µs | return $t unless ( my $ref = ref $t ); | ||
| 457 | 3470 | 6.88ms | 3470 | 981µs | return $t if $ref =~ /^Type::Tiny\b/; # spent 981µs making 3470 calls to Types::TypeTiny::CORE:match, avg 283ns/call |
| 458 | |||||
| 459 | return $ttt_cache{ refaddr( $t ) } if $ttt_cache{ refaddr( $t ) }; | ||||
| 460 | |||||
| 461 | #<<< | ||||
| 462 | if ( my $class = blessed $t) { | ||||
| 463 | return $t if $class->isa( "Type::Tiny" ); | ||||
| 464 | return _TypeTinyFromMoose( $t ) if $class eq "MooseX::Types::TypeDecorator"; # needed before MooseX::Types 0.35. | ||||
| 465 | return _TypeTinyFromMoose( $t ) if $class->isa( "Moose::Meta::TypeConstraint" ); | ||||
| 466 | return _TypeTinyFromMoose( $t ) if $class->isa( "MooseX::Types::TypeDecorator" ); | ||||
| 467 | return _TypeTinyFromMouse( $t ) if $class->isa( "Mouse::Meta::TypeConstraint" ); | ||||
| 468 | return _TypeTinyFromValidationClass( $t ) if $class->isa( "Validation::Class::Simple" ); | ||||
| 469 | return _TypeTinyFromValidationClass( $t ) if $class->isa( "Validation::Class" ); | ||||
| 470 | return $t->to_TypeTiny if $t->can( "DOES" ) && $t->DOES( "Type::Library::Compiler::TypeConstraint" ) && $t->can( "to_TypeTiny" ); | ||||
| 471 | return _TypeTinyFromGeneric( $t ) if $t->can( "check" ); # i.e. Type::API::Constraint | ||||
| 472 | } #/ if ( my $class = blessed...) | ||||
| 473 | #>>> | ||||
| 474 | |||||
| 475 | return _TypeTinyFromCodeRef( $t ) if $ref eq q(CODE); | ||||
| 476 | |||||
| 477 | $t; | ||||
| 478 | } #/ sub to_TypeTiny | ||||
| 479 | |||||
| 480 | sub _TypeTinyFromMoose { | ||||
| 481 | my $t = $_[0]; | ||||
| 482 | |||||
| 483 | if ( ref $t->{"Types::TypeTiny::to_TypeTiny"} ) { | ||||
| 484 | return $t->{"Types::TypeTiny::to_TypeTiny"}; | ||||
| 485 | } | ||||
| 486 | |||||
| 487 | if ( $t->name ne '__ANON__' ) { | ||||
| 488 | require Types::Standard; | ||||
| 489 | my $ts = 'Types::Standard'->get_type( $t->name ); | ||||
| 490 | return $ts if $ts->{_is_core}; | ||||
| 491 | } | ||||
| 492 | |||||
| 493 | #<<< | ||||
| 494 | my ( $tt_class, $tt_opts ) = | ||||
| 495 | $t->can( 'parameterize' ) ? _TypeTinyFromMoose_parameterizable( $t ) : | ||||
| 496 | $t->isa( 'Moose::Meta::TypeConstraint::Enum' ) ? _TypeTinyFromMoose_enum( $t ) : | ||||
| 497 | $t->isa( 'Moose::Meta::TypeConstraint::Class' ) ? _TypeTinyFromMoose_class( $t ) : | ||||
| 498 | $t->isa( 'Moose::Meta::TypeConstraint::Role' ) ? _TypeTinyFromMoose_role( $t ) : | ||||
| 499 | $t->isa( 'Moose::Meta::TypeConstraint::Union' ) ? _TypeTinyFromMoose_union( $t ) : | ||||
| 500 | $t->isa( 'Moose::Meta::TypeConstraint::DuckType' ) ? _TypeTinyFromMoose_ducktype( $t ) : | ||||
| 501 | _TypeTinyFromMoose_baseclass( $t ); | ||||
| 502 | #>>> | ||||
| 503 | |||||
| 504 | # Standard stuff to do with all type constraints from Moose, | ||||
| 505 | # regardless of variety. | ||||
| 506 | $tt_opts->{moose_type} = $t; | ||||
| 507 | $tt_opts->{display_name} = $t->name; | ||||
| 508 | $tt_opts->{message} = sub { $t->get_message( $_ ) } | ||||
| 509 | if $t->has_message; | ||||
| 510 | |||||
| 511 | my $new = $tt_class->new( %$tt_opts ); | ||||
| 512 | $ttt_cache{ refaddr( $t ) } = $new; | ||||
| 513 | weaken( $ttt_cache{ refaddr( $t ) } ); | ||||
| 514 | |||||
| 515 | $new->{coercion} = do { | ||||
| 516 | require Type::Coercion::FromMoose; | ||||
| 517 | 'Type::Coercion::FromMoose'->new( | ||||
| 518 | type_constraint => $new, | ||||
| 519 | moose_coercion => $t->coercion, | ||||
| 520 | ); | ||||
| 521 | } if $t->has_coercion; | ||||
| 522 | |||||
| 523 | return $new; | ||||
| 524 | } #/ sub _TypeTinyFromMoose | ||||
| 525 | |||||
| 526 | sub _TypeTinyFromMoose_baseclass { | ||||
| 527 | my $t = shift; | ||||
| 528 | my %opts; | ||||
| 529 | $opts{parent} = to_TypeTiny( $t->parent ) if $t->has_parent; | ||||
| 530 | $opts{constraint} = $t->constraint; | ||||
| 531 | $opts{inlined} = sub { shift; $t->_inline_check( @_ ) } | ||||
| 532 | if $t->can( "can_be_inlined" ) && $t->can_be_inlined; | ||||
| 533 | |||||
| 534 | # Cowardly refuse to inline types that need to close over stuff | ||||
| 535 | if ( $opts{inlined} ) { | ||||
| 536 | my %env = %{ $t->inline_environment || {} }; | ||||
| 537 | delete( $opts{inlined} ) if keys %env; | ||||
| 538 | } | ||||
| 539 | |||||
| 540 | require Type::Tiny; | ||||
| 541 | return 'Type::Tiny' => \%opts; | ||||
| 542 | } #/ sub _TypeTinyFromMoose_baseclass | ||||
| 543 | |||||
| 544 | sub _TypeTinyFromMoose_union { | ||||
| 545 | my $t = shift; | ||||
| 546 | my @mapped = map _TypeTinyFromMoose( $_ ), @{ $t->type_constraints }; | ||||
| 547 | require Type::Tiny::Union; | ||||
| 548 | return 'Type::Tiny::Union' => { type_constraints => \@mapped }; | ||||
| 549 | } | ||||
| 550 | |||||
| 551 | sub _TypeTinyFromMoose_enum { | ||||
| 552 | my $t = shift; | ||||
| 553 | require Type::Tiny::Enum; | ||||
| 554 | return 'Type::Tiny::Enum' => { values => [ @{ $t->values } ] }; | ||||
| 555 | } | ||||
| 556 | |||||
| 557 | sub _TypeTinyFromMoose_class { | ||||
| 558 | my $t = shift; | ||||
| 559 | require Type::Tiny::Class; | ||||
| 560 | return 'Type::Tiny::Class' => { class => $t->class }; | ||||
| 561 | } | ||||
| 562 | |||||
| 563 | sub _TypeTinyFromMoose_role { | ||||
| 564 | my $t = shift; | ||||
| 565 | require Type::Tiny::Role; | ||||
| 566 | return 'Type::Tiny::Role' => { role => $t->role }; | ||||
| 567 | } | ||||
| 568 | |||||
| 569 | sub _TypeTinyFromMoose_ducktype { | ||||
| 570 | my $t = shift; | ||||
| 571 | require Type::Tiny::Duck; | ||||
| 572 | return 'Type::Tiny::Duck' => { methods => [ @{ $t->methods } ] }; | ||||
| 573 | } | ||||
| 574 | |||||
| 575 | sub _TypeTinyFromMoose_parameterizable { | ||||
| 576 | my $t = shift; | ||||
| 577 | my ( $class, $opts ) = _TypeTinyFromMoose_baseclass( $t ); | ||||
| 578 | $opts->{constraint_generator} = sub { | ||||
| 579 | |||||
| 580 | # convert args into Moose native types; not strictly necessary | ||||
| 581 | my @args = map { is_TypeTiny( $_ ) ? $_->moose_type : $_ } @_; | ||||
| 582 | _TypeTinyFromMoose( $t->parameterize( @args ) ); | ||||
| 583 | }; | ||||
| 584 | return ( $class, $opts ); | ||||
| 585 | } #/ sub _TypeTinyFromMoose_parameterizable | ||||
| 586 | |||||
| 587 | sub _TypeTinyFromValidationClass { | ||||
| 588 | my $t = $_[0]; | ||||
| 589 | |||||
| 590 | require Type::Tiny; | ||||
| 591 | require Types::Standard; | ||||
| 592 | |||||
| 593 | my %opts = ( | ||||
| 594 | parent => Types::Standard::HashRef(), | ||||
| 595 | _validation_class => $t, | ||||
| 596 | ); | ||||
| 597 | |||||
| 598 | if ( $t->VERSION >= "7.900048" ) { | ||||
| 599 | $opts{constraint} = sub { | ||||
| 600 | $t->params->clear; | ||||
| 601 | $t->params->add( %$_ ); | ||||
| 602 | my $f = $t->filtering; | ||||
| 603 | $t->filtering( 'off' ); | ||||
| 604 | my $r = eval { $t->validate }; | ||||
| 605 | $t->filtering( $f || 'pre' ); | ||||
| 606 | return $r; | ||||
| 607 | }; | ||||
| 608 | $opts{message} = sub { | ||||
| 609 | $t->params->clear; | ||||
| 610 | $t->params->add( %$_ ); | ||||
| 611 | my $f = $t->filtering; | ||||
| 612 | $t->filtering( 'off' ); | ||||
| 613 | my $r = ( eval { $t->validate } ? "OK" : $t->errors_to_string ); | ||||
| 614 | $t->filtering( $f || 'pre' ); | ||||
| 615 | return $r; | ||||
| 616 | }; | ||||
| 617 | } #/ if ( $t->VERSION >= "7.900048") | ||||
| 618 | else # need to use hackish method | ||||
| 619 | { | ||||
| 620 | $opts{constraint} = sub { | ||||
| 621 | $t->params->clear; | ||||
| 622 | $t->params->add( %$_ ); | ||||
| 623 | 2 | 75µs | 2 | 66µs | # spent 37µs (8+29) within Types::TypeTiny::BEGIN@623 which was called:
# once (8µs+29µs) by Type::Tiny::BEGIN@21 at line 623 # spent 37µs making 1 call to Types::TypeTiny::BEGIN@623
# spent 29µs making 1 call to warnings::unimport |
| 624 | local *Validation::Class::Directive::Filters::execute_filtering = sub { $_[0] }; | ||||
| 625 | eval { $t->validate }; | ||||
| 626 | }; | ||||
| 627 | $opts{message} = sub { | ||||
| 628 | $t->params->clear; | ||||
| 629 | $t->params->add( %$_ ); | ||||
| 630 | 2 | 957µs | 2 | 21µs | # spent 13µs (5+8) within Types::TypeTiny::BEGIN@630 which was called:
# once (5µs+8µs) by Type::Tiny::BEGIN@21 at line 630 # spent 13µs making 1 call to Types::TypeTiny::BEGIN@630
# spent 8µs making 1 call to warnings::unimport |
| 631 | local *Validation::Class::Directive::Filters::execute_filtering = sub { $_[0] }; | ||||
| 632 | eval { $t->validate } ? "OK" : $t->errors_to_string; | ||||
| 633 | }; | ||||
| 634 | } #/ else [ if ( $t->VERSION >= "7.900048")] | ||||
| 635 | |||||
| 636 | require Type::Tiny; | ||||
| 637 | my $new = "Type::Tiny"->new( %opts ); | ||||
| 638 | |||||
| 639 | $new->coercion->add_type_coercions( | ||||
| 640 | Types::Standard::HashRef() => sub { | ||||
| 641 | my %params = %$_; | ||||
| 642 | for my $k ( keys %params ) { delete $params{$_} unless $t->get_fields( $k ) } | ||||
| 643 | $t->params->clear; | ||||
| 644 | $t->params->add( %params ); | ||||
| 645 | eval { $t->validate }; | ||||
| 646 | $t->get_hash; | ||||
| 647 | }, | ||||
| 648 | ); | ||||
| 649 | |||||
| 650 | $ttt_cache{ refaddr( $t ) } = $new; | ||||
| 651 | weaken( $ttt_cache{ refaddr( $t ) } ); | ||||
| 652 | return $new; | ||||
| 653 | } #/ sub _TypeTinyFromValidationClass | ||||
| 654 | |||||
| 655 | sub _TypeTinyFromGeneric { | ||||
| 656 | my $t = $_[0]; | ||||
| 657 | |||||
| 658 | my %opts = ( | ||||
| 659 | constraint => sub { $t->check( @_ ? @_ : $_ ) }, | ||||
| 660 | ); | ||||
| 661 | |||||
| 662 | $opts{message} = sub { $t->get_message( @_ ? @_ : $_ ) } | ||||
| 663 | if $t->can( "get_message" ); | ||||
| 664 | |||||
| 665 | $opts{display_name} = $t->name if $t->can( "name" ); | ||||
| 666 | |||||
| 667 | $opts{coercion} = sub { $t->coerce( @_ ? @_ : $_ ) } | ||||
| 668 | if $t->can( "has_coercion" ) | ||||
| 669 | && $t->has_coercion | ||||
| 670 | && $t->can( "coerce" ); | ||||
| 671 | |||||
| 672 | if ( $t->can( 'can_be_inlined' ) | ||||
| 673 | && $t->can_be_inlined | ||||
| 674 | && $t->can( 'inline_check' ) ) | ||||
| 675 | { | ||||
| 676 | $opts{inlined} = sub { $t->inline_check( $_[1] ) }; | ||||
| 677 | } | ||||
| 678 | |||||
| 679 | require Type::Tiny; | ||||
| 680 | my $new = "Type::Tiny"->new( %opts ); | ||||
| 681 | $ttt_cache{ refaddr( $t ) } = $new; | ||||
| 682 | weaken( $ttt_cache{ refaddr( $t ) } ); | ||||
| 683 | return $new; | ||||
| 684 | } #/ sub _TypeTinyFromGeneric | ||||
| 685 | |||||
| 686 | sub _TypeTinyFromMouse { | ||||
| 687 | my $t = $_[0]; | ||||
| 688 | |||||
| 689 | my %opts = ( | ||||
| 690 | constraint => sub { $t->check( @_ ? @_ : $_ ) }, | ||||
| 691 | message => sub { $t->get_message( @_ ? @_ : $_ ) }, | ||||
| 692 | ); | ||||
| 693 | |||||
| 694 | $opts{display_name} = $t->name if $t->can( "name" ); | ||||
| 695 | |||||
| 696 | $opts{coercion} = sub { $t->coerce( @_ ? @_ : $_ ) } | ||||
| 697 | if $t->can( "has_coercion" ) | ||||
| 698 | && $t->has_coercion | ||||
| 699 | && $t->can( "coerce" ); | ||||
| 700 | |||||
| 701 | if ( $t->{'constraint_generator'} ) { | ||||
| 702 | $opts{constraint_generator} = sub { | ||||
| 703 | |||||
| 704 | # convert args into Moose native types; not strictly necessary | ||||
| 705 | my @args = map { is_TypeTiny( $_ ) ? $_->mouse_type : $_ } @_; | ||||
| 706 | _TypeTinyFromMouse( $t->parameterize( @args ) ); | ||||
| 707 | }; | ||||
| 708 | } | ||||
| 709 | |||||
| 710 | require Type::Tiny; | ||||
| 711 | my $new = "Type::Tiny"->new( %opts ); | ||||
| 712 | $ttt_cache{ refaddr( $t ) } = $new; | ||||
| 713 | weaken( $ttt_cache{ refaddr( $t ) } ); | ||||
| 714 | return $new; | ||||
| 715 | } #/ sub _TypeTinyFromMouse | ||||
| 716 | |||||
| 717 | my $QFS; | ||||
| 718 | |||||
| 719 | sub _TypeTinyFromCodeRef { | ||||
| 720 | my $t = $_[0]; | ||||
| 721 | |||||
| 722 | my %opts = ( | ||||
| 723 | constraint => sub { | ||||
| 724 | return !!eval { $t->( $_ ) }; | ||||
| 725 | }, | ||||
| 726 | message => sub { | ||||
| 727 | local $@; | ||||
| 728 | eval { $t->( $_ ); 1 } or do { chomp $@; return $@ if $@ }; | ||||
| 729 | return sprintf( '%s did not pass type constraint', Type::Tiny::_dd( $_ ) ); | ||||
| 730 | }, | ||||
| 731 | ); | ||||
| 732 | |||||
| 733 | if ( $QFS ||= "Sub::Quote"->can( "quoted_from_sub" ) ) { | ||||
| 734 | my ( undef, $perlstring, $captures ) = @{ $QFS->( $t ) || [] }; | ||||
| 735 | if ( $perlstring ) { | ||||
| 736 | $perlstring = "!!eval{ $perlstring }"; | ||||
| 737 | $opts{inlined} = sub { | ||||
| 738 | my $var = $_[1]; | ||||
| 739 | Sub::Quote::inlinify( | ||||
| 740 | $perlstring, | ||||
| 741 | $var, | ||||
| 742 | $var eq q($_) ? '' : "local \$_ = $var;", | ||||
| 743 | 1, | ||||
| 744 | ); | ||||
| 745 | } | ||||
| 746 | if $perlstring && !$captures; | ||||
| 747 | } #/ if ( $perlstring ) | ||||
| 748 | } #/ if ( $QFS ||= "Sub::Quote"...) | ||||
| 749 | |||||
| 750 | require Type::Tiny; | ||||
| 751 | my $new = "Type::Tiny"->new( %opts ); | ||||
| 752 | $ttt_cache{ refaddr( $t ) } = $new; | ||||
| 753 | weaken( $ttt_cache{ refaddr( $t ) } ); | ||||
| 754 | return $new; | ||||
| 755 | } #/ sub _TypeTinyFromCodeRef | ||||
| 756 | |||||
| 757 | 1 | 11µs | 1; | ||
| 758 | |||||
| 759 | __END__ | ||||
# spent 981µs within Types::TypeTiny::CORE:match which was called 3470 times, avg 283ns/call:
# 3470 times (981µs+0s) by Types::TypeTiny::to_TypeTiny at line 457, avg 283ns/call |