File Coverage

blib/lib/returning.pm
Criterion Covered Total %
statement 55 59 93.2
branch 10 16 62.5
condition 1 3 33.3
subroutine 19 19 100.0
pod 1 1 100.0
total 86 98 87.7


line stmt bran cond sub pod time code
1             package returning;
2              
3 1     1   20746 use 5.006;
  1         5  
  1         30  
4 1     1   4 use strict;
  1         2  
  1         25  
5 1     1   5 no warnings;
  1         5  
  1         54  
6              
7             BEGIN {
8 1     1   1 $returning::AUTHORITY = 'cpan:TOBYINK';
9 1         21 $returning::VERSION = '0.002';
10             }
11              
12 1     1   4 use Carp 1.01 qw( croak );
  1         22  
  1         69  
13 1     1   5 use Scalar::Util 1.11 qw( set_prototype );
  1         22  
  1         87  
14 1     1   833 use Scope::Upper 0.16 qw( :all );
  1         1007  
  1         188  
15 1     1   950 use Sub::Install 0.900 qw( install_sub reinstall_sub );
  1         1815  
  1         7  
16 1     1   943 use Sub::Name 0.03 qw( subname );
  1         557  
  1         415  
17              
18             sub import
19             {
20 1     1   18 my $class = shift;
21 1         1 my $default_target = caller;
22            
23 1         3 foreach my $arg (@_)
24             {
25 1 50       4 if (ref $arg eq 'HASH')
    0          
26             {
27 1   33     9 my $target = $arg->{-into} || $default_target;
28 1         3 foreach my $func (keys %$arg)
29             {
30 5 50       198 next unless $func =~ /^[^\W\d]\w*$/;
31            
32 5         8 my $v = $arg->{$func};
33 5 50   1   12 my $code = ('CODE' eq ref $v) ? $v : sub(){$v if $]};
  1 100       13  
34            
35 5         46 install_sub {
36             code => subname("$target\::$func", $code),
37             into => $target,
38             as => $func,
39             };
40            
41 5         178 $class->setup_for($target, $func);
42             }
43             }
44            
45             elsif ($arg =~ /^[^\W\d]\w*$/)
46             {
47 0         0 $class->setup_for($default_target, $arg);
48             }
49            
50             else
51             {
52 0         0 croak "unrecognised import argument to returning: $arg";
53             }
54             }
55             }
56              
57             sub setup_for
58             {
59 5     5 1 9 my ($class, $target, $func) = @_;
60            
61             my $orig_code = do
62 5         4 {
63 1     1   6 no strict 'refs';
  1         1  
  1         196  
64 5         4 \&{"$target\::$func"};
  5         13  
65             };
66            
67             my $new_code = sub
68             {
69 6     6   44 my $cx = SUB UP;
        6      
        6      
        6      
        6      
        6      
70 6         20 my $want = want_at $cx;
71 6         8 my @result;
72 6 100       17 if ($want)
    50          
73 1         7 { @result = &uplevel($orig_code, @_, $cx) }
74             elsif (defined $want)
75 5         38 { @result = scalar &uplevel($orig_code, @_, $cx) }
76             else
77 0         0 { &uplevel($orig_code, @_, $cx); @result = undef }
  0         0  
78 6         70 unwind @result => $cx;
79 5         15 };
80            
81 5 100       15 &set_prototype(
82             $new_code,
83             prototype($orig_code),
84             )
85             if defined prototype($orig_code);
86            
87 5         41 reinstall_sub {
88             code => subname("$target\::$func", $new_code),
89             into => $target,
90             as => $func,
91             };
92             }
93              
94             __PACKAGE__
95             __END__