File Coverage

blib/lib/Sub/Data/Recursive.pm
Criterion Covered Total %
statement 30 36 83.3
branch 9 14 64.2
condition 0 3 0.0
subroutine 5 5 100.0
pod 1 1 100.0
total 45 59 76.2


line stmt bran cond sub pod time code
1             package Sub::Data::Recursive;
2 3     3   113004 use strict;
  3         9  
  3         129  
3 3     3   19 use warnings FATAL => 'all';
  3         10  
  3         173  
4              
5             our $VERSION = '0.01';
6              
7 3     3   18 use Scalar::Util qw/refaddr/;
  3         13  
  3         1494  
8              
9             sub invoke {
10 6     6 1 4128 my ($class, $code, @args) = @_;
11 6         22 _apply($code, +{}, @args);
12             }
13              
14             sub _apply {
15 20     20   29 my $code = shift;
16 20         21 my $seen = shift;
17              
18 20         21 my @retval;
19 20         35 for my $arg (@_) {
20 43 100       172 if(my $ref = ref $arg){
21 14         35 my $refaddr = refaddr($arg);
22 14         18 my $proto;
23              
24 14 50 0     61 if(defined($proto = $seen->{$refaddr})){
    100          
    50          
    0          
25             # noop
26             }
27             elsif($ref eq 'ARRAY'){
28 3         9 $proto = $seen->{$refaddr} = [];
29 3         6 @{$proto} = _apply($code, $seen, @{$arg});
  3         9  
  3         11  
30             }
31             elsif($ref eq 'HASH'){
32 11         28 $proto = $seen->{$refaddr} = {};
33 11         15 %{$proto} = _apply($code, $seen, %{$arg});
  11         48  
  11         55  
34             }
35             elsif($ref eq 'REF' or $ref eq 'SCALAR'){
36 0         0 $proto = $seen->{$refaddr} = \do{ my $scalar };
  0         0  
37 0         0 ${$proto} = _apply($code, $seen, ${$arg});
  0         0  
  0         0  
38             }
39             else{ # CODE, GLOB, IO, LVALUE etc.
40 0         0 $proto = $seen->{$refaddr} = $arg;
41             }
42              
43 14         41 push @retval, $proto;
44             }
45             else{
46 29 50       80 push @retval, defined($arg) ? $code->($arg) : $arg;
47             }
48             }
49              
50 20 100       112 return wantarray ? @retval : $retval[0];
51             }
52              
53             1;
54              
55             __END__