File Coverage

blib/lib/Sub/Caller.pm
Criterion Covered Total %
statement 41 53 77.3
branch 13 24 54.1
condition 9 15 60.0
subroutine 7 7 100.0
pod 0 3 0.0
total 70 102 68.6


line stmt bran cond sub pod time code
1             package Sub::Caller;
2              
3             require DynaLoader;
4              
5             our $VERSION = '0.60';
6             our @ISA = qw(DynaLoader);
7             bootstrap Sub::Caller;
8             ################################
9             my %change;
10              
11             ##
12             ## We have to delay messing with functions
13             ## until Perl has them all loaded.
14             ##
15             sub import {
16 2     2   16 shift;
17 2         1539 $change{caller()} = \@_;
18             }
19              
20             ##
21             ## Now we can mess with functions
22             ##
23             sub CHECK {
24 2     2   15 for my $k (keys %change){
25 2         7 addCaller([$k], @{$change{$k}});
  2         10  
26             }
27             }
28              
29              
30             my $addCaller = sub {
31 2     2   11 my ($CALL, $call) = ({package=>undef, function=>undef, line=>undef, file=>undef}, 0);
32 2 50       6 my $frames = @_?shift():5;
33              
34 4         4 WR_GET_CALLER_FUNC:
35             $call++;
36 4         16 ($CALL->{function}) = (caller $call)[3];
37              
38             ## Keep going until we find an actual function call
39 4 100 100     41 if ($CALL->{function} && $CALL->{function} =~ /ANON/ && $call < $frames){
    50 66        
40 2         13 goto WR_GET_CALLER_FUNC;
41             }
42             elsif ($call < $frames){
43 0         0 my ($c) = (caller ++$call)[3];
44 0 0 0     0 $call-- and goto WR_GET_CALLER_FUNC if $c;
45             }
46              
47 2         8 $CALL->{function} =~ s/(.*):://;
48 2   100     11 $CALL->{package} = $1 || "main";
49 2   100     7 $CALL->{function} ||= "main";
50 2         9 @$CALL{qw(file line)} = (caller(1))[1,2];
51              
52 2         6 bless $CALL;
53             };
54              
55              
56             sub addCaller {
57 3 50   3 0 14 if (@_){
58 3 100       15 my ($pkg) = ref $_[0]?shift()->[0]:caller();
59              
60 3 50       16 if ($_[0] =~ /all/i){
61 0         0 shift;
62 0         0 for my $f (keys %{$pkg."::"}){
  0         0  
63 0 0 0     0 push @_, $f if (defined &{$pkg."::$f"} && checkFunc(\&{$pkg."::$f"}) eq $pkg);
  0         0  
  0         0  
64             }
65             }
66              
67 3         10 modifyCaller($pkg, @_);
68              
69 3 100       4 if (!defined &{$pkg."::aDdCaLLer"}){
  3         25  
70 2         3 *{$pkg."::aDdCaLLer"} = $addCaller;
  2         1926  
71             }
72             }
73             }
74              
75              
76 3     3 0 55 sub isCaller { ref $_[0] eq __PACKAGE__; }
77              
78              
79             sub modifyCaller {
80 3     3 0 5 my ($pkg) = shift();
81              
82 3         10 for my $f (@_){
83             ## Don't do anything for non-existant functions
84 1 50       2 if (!defined(&{$pkg."::$f"})){ next; }
  1         9  
  0         0  
85              
86             ## Don't re-re-define functions else we get infinite loops
87 1 50       2 if (defined(&{$pkg."::_$f"})){ next; }
  1         7  
  0         0  
88              
89             ## Create copy of original sub
90 1         2 *{$pkg."::_$f"} = \&{$pkg."::$f"};
  1         5  
  1         4  
91              
92             ## Replace original sub with new version
93 1         5 *{$pkg."::$f"} = sub {
94 2     2   2 my $CALL = &{$pkg."::aDdCaLLer"}(2);
  2         10  
95             ## Call original sub with caller data at end of stack
96 2 50       6 if ($pkg eq 'main'){
97 2         3 &{$pkg."::_$f"}(@_, $CALL);
  2         9  
98             }
99             ## Make sure objects get the package name first
100             else{
101 0           &{$pkg."::_$f"}($pkg, @_[1..$#_], $CALL);
  0            
102             }
103 1         6 };
104             }
105             }
106              
107             1;
108             __END__