CC: | chromatic <chromatic [...] wgz.org> |
Subject: | Bugs in Devel::TraceUse |
Date: | Sun, 24 Jan 2010 20:58:35 +0100 |
To: | bug-devel-traceuse [...] rt.cpan.org |
From: | "Philippe Bruhat (BooK)" <philippe.bruhat [...] free.fr> |
Hi,
While using Devel::TraceUse on a large hierachy of modules, I found
several issues with it.
The first one would be related to Heisenberg's principle (not really, but
that's what jumped to my mind when I realized what was happening).
$ grep '^use ' lib/Devel/TraceUse.pm
use strict;
use warnings;
use vars '$VERSION';
use Time::HiRes qw( gettimeofday tv_interval );
These four modules (and the modules they load) will disappear from the
hierarchy, since they are loaded before the trace_use() routine is put
in @INC.
Running the BEGIN block earlier wouldn't help (if that was even possible),
because we would then see these modules when they are first loaded,
i.e. when Devel::TraceUse is loaded, which would bring us back to
Heisenberg's principle: looking at the modules being loaded in our
program would indeed change the module loading order.
Anyway, the patch for this is ultimately very simple, as wiping %INC
should hide whatever Devel::TraceUse may have loaded (see first
attachement).
Before:
$ perl -Ilib -d:TraceUse -MGetopt::Long -e1
Modules used from -e:
Getopt::Long, line 0 (9.8e-05)
constant, line 226 (8.3e-05)
overload, line 1487 (0.000108)
After:
$ perl -Ilib -d:TraceUse -MGetopt::Long -e1
Modules used from -e:
Getopt::Long, line 0 (8.4e-05)
strict, line 35 (8e-05)
vars, line 37 (7.5e-05)
warnings::register, line 7 (8.6e-05)
warnings, line 24 (7.5e-05)
Exporter, line 43 (9.2e-05)
constant, line 226 (8.8e-05)
overload, line 1487 (8.9e-05)
Exporter::Heavy, line 18 (7.7e-05)
With this output, new issues then become apparent:
* overload doesn't use Exporter::Heavy (Exporter does require it)
* constant doesn't use overload (Getopt::Long does use it, in the
package Getopt::Long::CallBack --this was already visible in the
original version of Devel::TraceUse)
There are actually two problems here:
* require happens at run time, long after the original module was loaded,
and that messes up the tree-building algorithm
* the tree-building algorithm assumes that a package is contained in a file
by the same name, which is not the case for Getopt::Long::CallBack, which
lives in Getopt/Long.pm
These problems can be fixed by changing the output.
If I understood correctly, it is really hard to find out if a module is
loaded via require or use. I thought that a better option would be
to simply record the loading order, and add it in a first column, while
keeping a tree-like output.
The proposed output shows the proper tree structure, the load order,
the module loaded, the loading filename (not the full filename, just
the relevant part), optionally the loading package (if different from
the file containing the use or require statement) and the loading time.
The output of the previous example looks like this:
$ perl -Ilib -d:TraceUse -MGetopt::Long -e1
Modules used from -e:
1. Getopt::Long, -e line 0 [main] (9.1e-05)
2. strict, Getopt/Long.pm line 35 (7.1e-05)
3. vars, Getopt/Long.pm line 37 (7.7e-05)
4. warnings::register, vars.pm line 7 (7.8e-05)
5. warnings, warnings/register.pm line 24 (7.7e-05)
6. Exporter, Getopt/Long.pm line 43 (8.8e-05)
9. Exporter::Heavy, Exporter.pm line 18 (8.4e-05)
7. constant, Getopt/Long.pm line 226 (8.3e-05)
8. overload, Getopt/Long.pm line 1487 [Getopt::Long::CallBack] (9.1e-05)
The second attached patch produces the output described above .
--
Philippe Bruhat (BooK)
The only certain bet in gambling is that it leads to more gambling
(Moral from Groo #11 (Image))
Message body is not shown because sender requested not to inline it.
Message body is not shown because sender requested not to inline it.