File Coverage

blib/lib/Type/Coercion/Wrapped.pm
Criterion Covered Total %
statement 36 51 70.5
branch 6 18 33.3
condition 4 15 26.6
subroutine 8 9 88.8
pod 2 2 100.0
total 56 95 58.9


line stmt bran cond sub pod time code
1 5     5   90 use 5.008;
  5         17  
  5         194  
2 5     5   28 use strict;
  5         5  
  5         133  
3 5     5   26 use warnings;
  5         9  
  5         288  
4              
5             package Type::Coercion::Wrapped;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.002';
9              
10 5     5   31 use base 'Type::Coercion';
  5         9  
  5         427  
11 5     5   25 use Scalar::Util 'weaken';
  5         8  
  5         2491  
12              
13             sub _build_compiled_coercion {
14 4     4   15173 my $self = shift;
15            
16 4 50       16 return $self->SUPER::_build_compiled_coercion(@_)
17             if $self->can_be_inlined;
18            
19 0         0 my $type = $self->type_constraint;
20 0         0 my $pre = $type->pre_coerce;
21 0         0 my $orig = $self->SUPER::_build_compiled_coercion(@_);
22 0         0 my $post = $type->post_coerce;
23            
24 0 0 0     0 return $orig unless $pre || $post;
25            
26 0         0 weaken $type;
27             return sub {
28 0     0   0 local $_ = $_[0];
29 0 0       0 $_ = $pre->($type, $_) if defined($pre);
30 0         0 $_ = $orig->($_);
31 0 0       0 $_ = $post->($type, $_) if defined($post);
32 0         0 return $_;
33 0         0 };
34             }
35              
36             my $counter = 0;
37             sub inline_coercion {
38 7     7 1 642 my $self = shift;
39 7         19 local $_ = (my $varname = $_[0]);
40            
41 7         40 my $tc = $self->type_constraint;
42 7   33     63 my $pre = $tc && $tc->inlined_pre_coerce;
43 7   33     27 my $post = $tc && $tc->inlined_post_coerce;
44            
45 7         18 my $code = '';
46 7 50       32 if ($pre) {
47 0         0 my $tmpvar = sprintf('$__TypeCoercionWrappedTmp%d', ++$counter);
48 0         0 $code .= sprintf('my %s = do { no warnings; %s };', $tmpvar, $pre->($tc, $varname));
49 0         0 $_ = $varname = $tmpvar;
50             }
51            
52 7         13 do {
53 7         32 my $tmpvar = sprintf('$__TypeCoercionWrappedTmp%d', ++$counter);
54 7         64 $code .= sprintf('my %s = do { no warnings; %s };', $tmpvar, $self->SUPER::inline_coercion($varname));
55 7         18807 $_ = $varname = $tmpvar;
56             };
57            
58 7 50       31 if ($post) {
59 7         35 $code .= sprintf('do { no warnings; %s };', $post->($tc, $varname));
60             }
61            
62 7         75 "do { no warnings; $code }";
63             }
64              
65             sub can_be_inlined {
66 20     20 1 9637 my $self = shift;
67 20 50       88 if (my $tc = $self->type_constraint) {
68 20 50 33     298 return if $tc->pre_coerce && !$tc->inlined_pre_coerce;
69 20 50 33     67 return if $tc->post_coerce && !$tc->inlined_post_coerce;
70             }
71 20         121 return $self->SUPER::can_be_inlined;
72             }
73              
74             1;
75              
76             __END__