File Coverage

blib/lib/Devel/CompiledCalls.pm
Criterion Covered Total %
statement 43 47 91.4
branch 6 6 100.0
condition n/a
subroutine 10 11 90.9
pod 1 1 100.0
total 60 65 92.3


line stmt bran cond sub pod time code
1             package Devel::CompiledCalls;
2              
3 3     3   96278 use 5.008;
  3         12  
  3         303  
4              
5 3     3   18 use strict;
  3         6  
  3         99  
6 3     3   15 use warnings;
  3         10  
  3         105  
7              
8 3     3   2813 use B::Compiling qw( PL_compiling );
  3         62936  
  3         20  
9 3         283 use B::CallChecker qw(
10             cv_get_call_checker
11             cv_set_call_checker
12 3     3   3603 );
  3         12893  
13 3     3   2500 use Sub::Identify qw(sub_fullname);
  3         2662  
  3         983  
14              
15             our $VERSION = "2.00";
16              
17             =head1 NAME
18              
19             Devel::CompiledCalls - show where calls to a named subroutine are compiled
20              
21             =head1 SYNOPSIS
22              
23             # from the shell
24             shell$ perl -c -MDevel::CompiledCalls=Data::Dumper::Dumper myscript.pl
25             Data::Dumper::Dumper call at myscript.pl line 4.
26             Data::Dumper::Dumper call at myscript.pl line 5.
27             myscript.pl syntax OK
28              
29             # from within a Perl script
30             use Devel::CompiledCalls qw(Data::Dumper::Dumper);
31              
32             # from a perl script with custom callback
33             use Devel::CompiledCalls;
34             BEGIN {
35             Devel::CompiledCalls::attach_callback("Data::Dumper::Dumper", sub {
36             my ($subname, $filename, $line) = @_;
37             say "$subname at $line of $filename";
38             });
39             };
40              
41             =head1 DESCRIPTION
42              
43             This module allows you to put hooks into Perl so that whenever a call to
44             a named subroutine has been compiled a callback is fired. The easiest syntax
45             (import Devel::CompiledCalls and pass the name of the subroutine) simply
46             logs the line and filename of the call to STDERR.
47              
48             Note that since we are hooking the process of compiling not the execution of
49             the subroutines (technically, we're hooking the process of subroutine parameter
50             checking, but the effects are the same) this module will find calls that aren't
51             normally captured by modules like Hook::LexWrap because they're not normally
52             executed during the program's execution (e.g. a call in exception handling code
53             that only occurs once every four years.)
54              
55             =head2 Use with import
56              
57             The simpliest way to to hook is to pass the name of the function in the
58             import list:
59              
60             use Devel::CompiledCalls qw(foo);
61             ...
62              
63             Or from the command line:
64              
65             perl -MDevel::CompiledCalls=foo -e '...'
66              
67             In both these cases the standard callback - which simply prints to STDERR - will
68             be installed.
69              
70             =head2 Custom callbacks
71              
72             Custom callbacks can be installed with the C subroutine.
73             This routine is not exported and must be called with a fully qualified
74             function call.
75              
76             =over
77              
78             =item attach_callback( $subroutine_ref, $callback )
79              
80             =item attach_callback( $subroutine_name, $callback )
81              
82             The callback will be called whenever a call to the subroutine is compiled. The
83             subroutine can either be passed by reference, by fully qualified name (including
84             the package,) or by just the subroutine name (in which case it will be assumed
85             to be in the same package as C is called from.)
86              
87             The callback will be executed with three parameters: The name of the subroutine,
88             the filename of the source file, and the the line of the sourcefile that
89             contains the subroutine.
90              
91             =back
92              
93             =cut
94              
95             sub import {
96 3     3   29 shift;
97             attach_callback($_, sub {
98 0     0   0 my ($name, $file, $line,$stash) = @_;
99 0         0 local $\ = undef; # locally reset back to default just in case
100 0         0 print {*STDERR} "$name call at $file line $line.\n";
  0         0  
101 3         9 }) foreach @_;
102 3         172 return;
103             }
104              
105             sub attach_callback {
106 3     3 1 18 my $name = shift;
107 3         21 my $callback = shift;
108              
109             # check for an unqualifed subroutine name. If we have one
110             # then we need to give it our *caller's* package (or, potentially
111             # our caller's caller package
112             my $fully_qualified_name =
113             ref $name eq "CODE" ? $name :
114 3 100       20 $name =~ /::/x ? $name : do {
    100          
115 1         1 my $caller_package;
116 1         2 my $level = 1;
117 1         1 do { ($caller_package) = caller($level++) }
  1         10  
118             while ($caller_package eq __PACKAGE__);
119 1         3 $caller_package.'::'.$name;
120             };
121 3 100       13 $name = sub_fullname($name) if ref($name) eq "CODE";
122              
123             # get the sub (this will spring into existence with autovivication
124             # if needed)
125 3     3   20 my $uboat = do { no strict 'subs'; \&{$fully_qualified_name} };
  3         6  
  3         536  
  3         10  
  3         5  
  3         18  
126              
127             # work out what original check would have been made
128 3         12 my ($original_check, $data) = cv_get_call_checker($uboat);
129              
130             # install our own checker that doesn't actually do any checking
131             # but instead simply calls the callback
132             cv_set_call_checker($uboat, sub {
133              
134 7     7   27036 my $file = PL_compiling->file;
135 7         36 my $line = PL_compiling->line;
136 7         23 $callback->($name, $file, $line);
137              
138             # return the results of making the normal check
139 7         5666 return $original_check->(@_);
140 3         20 }, $data);
141 3         58 return;
142             }
143              
144             =head1 BUGS
145              
146             This module can't find calls that aren't compiled until the point they are
147             actually compiled. For example this code:
148              
149             use Devel::CompiledCalls qw(foo);
150             sub foo { ... }
151             sub fred { eval "foo('bar')" }
152              
153             Won't print out until C is executed, since the call C is not
154             compiled until that point. A similar problem happens with modules that are
155             loaded at runtime on demand; Until the module is loaded the code is not
156             compiled and nothing is printed until such compilation happens.
157              
158             Also, this module can't find calls that are constructed in any way other
159             than standard function calling. For example accessing the
160             symbolic name of the function directly. This won't print anything:
161              
162             use Devel::CompiledCalls qw(foo);
163             sub foo { ... }
164             my $uboat = \&{"foo"};
165             $uboat->();
166              
167             As no subroutine call is actually compiled. Similarly this won't print
168             anything either:
169              
170             use Devel::CompiledCalls qw(foo);
171             sub foo { ... }
172             &foo;
173             &foo("whatever");
174              
175             Because the use of the C<&> sigil disables prototype checking which is
176             what we're hooking to record the call.
177              
178             Using this module has the effect of making the subroutine we are hooking
179             "exist". i.e.
180              
181             use Devel::CompiledCalls qw(foo);
182             say "YES" if exists &foo;
183              
184             Prints C out even before we define the subroutine foo anywhere.
185              
186             Bugs (and requests for new features) can be reported though the CPAN
187             RT system:
188             L
189              
190             Alternatively, you can simply fork this project on github and
191             send me pull requests. Please see L
192              
193             =head1 AUTHOR
194              
195             Written by Mark Fowler B.
196              
197             Copyright Mark Fowler 2012.
198              
199             This program is free software; you can redistribute it and/or modify
200             it under the same terms as Perl itself.
201              
202             =head1 SEE ALSO
203              
204             L allows you to hook subroutines whenever they
205             are called.
206              
207             L and L were used in the construction of this
208             module, but I don't expose any user-accessible parts.
209              
210             =cut
211              
212             1;