perl5ever has asked for the wisdom of the Perl Monks concerning the following question:

I'm using Devel::TraceUse with a script that uses the 'lib' module:
use lib 'my-lib'; use Fcntl;

Running perl -d:TraceUse script.pl results in:

Modules used from ./script.pl: lib, line 2 (0.003514) Fcntl, line 1 (0.000265) Fcntl, line 1 (0.000531) Fcntl, line 1 (0.000847) Fcntl, line 1 (0.001094) Fcntl, line 8 (0.001204) XSLoader, line 1 (1.7e-05) XSLoader, line 1 (0.000449) XSLoader, line 1 (0.000715) XSLoader, line 1 (0.000965) XSLoader, line 61 (0.001219)
If I add a for (@INC) { print "INC: $_\n" } after the use lib line, I get this output:
INC: my-lib/5.8.8/i386-linux-thread-multi INC: my-lib/5.8.8 INC: my-lib/5.8.6 INC: my-lib INC: CODE(0x98f8e08) INC: ...(lots of other directories omitted)... ... Modules used from ./script.pl: lib, line 2 (0.003122) Fcntl, line 1 (0.000253) Fcntl, line 1 (0.000494) Fcntl, line 1 (0.000747) Fcntl, line 1 (0.000995) Fcntl, line 8 (0.001262) XSLoader, line 1 (0.0002) XSLoader, line 1 (0.000423) XSLoader, line 1 (0.000659) XSLoader, line 1 (0.000736) XSLoader, line 61 (0.001646)
So it seems that when use lib adds multiple directories to @INC things go screwy for Devel::TraceUse.

I haven't run into this problem if use lib 'my-lib' only adds one directory to @INC.

Is there a way to fix this?

Replies are listed 'Best First'.
Re: Devel::TraceUse bizarreness
by ikegami (Patriarch) on Jul 05, 2009 at 18:14 UTC

    I assume Devel:TraceUse is placing that code ref in @INC. If so, I'm guessing Devel::TraceUse needs to be loaded after all modifications to @INC have been made. If so, the first snippet below will exhibit the problem, but not the latter.

    perl -d:TraceUse -Mlib=my-lib -e'use Fcntl'
    and
    perl -Mlib=my-lib -d:TraceUse -e'use Fcntl'

    I can't verify this because the module fails its tests.

Re: Devel::TraceUse bizarreness
by perl5ever (Pilgrim) on Jul 06, 2009 at 15:45 UTC
    Figured it out... Devel::TraceUse assumes it is the first module in the @INC list:
    ... { local *INC = [ @INC[ 1 .. $#INC ] ]; my $start_time = [ gettimeofday() ]; eval "package $package; require '$mod_name';"; $elapsed = tv_interval($start_time); } ...
    Another approach would be to tie @INC to an array implementation which always puts the coderef used by Devel::TraceUse at the beginning of the array. That is, regardless of whatever array operations you performed on @INC, $INC[0] would always return TraceUse's coderef.

    The real solution is to just redefine require if that's possible.

Re: Devel::TraceUse bizarreness
by Khen1950fx (Canon) on Jul 06, 2009 at 19:45 UTC
    I couldn't replicate the problem, but I tried it using Find::Lib.

    #!/usr/local/bin/perl use strict; use warnings; use Find::Lib 'my-lib'; use Fcntl qw(:DEFAULT :flock); for (@INC) { print "INC : $_\n" }