Last active
October 13, 2017 17:25
-
-
Save exodist/708d8b41af5de51f92abb4b38a266aba to your computer and use it in GitHub Desktop.
DepTracer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package DepTracer; | |
use strict; | |
use warnings; | |
use Object::HashBase qw/ | |
-_on | |
-exclude | |
-dep_map | |
-loaded | |
-my_require | |
-real_require | |
/; | |
my %DEFAULT_EXCLUDE = ( | |
'warnings.pm' => 1, | |
'strict.pm' => 1, | |
); | |
sub start { shift->{+_ON} = 1 } | |
sub stop { shift->{+_ON} = 0 } | |
sub clear_loaded { %{$_[0]->{+LOADED}} = () } | |
my %REQUIRE_CACHE; | |
sub init { | |
my $self = shift; | |
my $exclude = $self->{+EXCLUDE} ||= { %DEFAULT_EXCLUDE }; | |
my $stash = \%CORE::GLOBAL::; | |
# We use a string in the reference below to prevent the glob slot from | |
# being auto-vivified by the compiler. | |
$self->{+REAL_REQUIRE} = exists $stash->{require} ? \&{'CORE::GLOBAL::require'} : undef; | |
my $dep_map = $self->{+DEP_MAP} ||= {}; | |
my $loaded = $self->{+LOADED} ||= {}; | |
my %seen; | |
my $require = $self->{+MY_REQUIRE} = sub { | |
my ($file) = @_; | |
my $loaded_by = $self->loaded_by; | |
my $real_require = $self->{+REAL_REQUIRE}; | |
unless($real_require) { | |
my $caller = $loaded_by->[0]; | |
$real_require = $REQUIRE_CACHE{$caller} ||= eval "package $caller; sub { CORE::require(\$_[0]) }" or die $@; | |
} | |
goto &$real_require unless $self->{+_ON}; | |
if ($file =~ m/^[_a-z]/i) { | |
unless ($exclude->{$file}) { | |
push @{$dep_map->{$file}} => $loaded_by; | |
$loaded->{$file}++; | |
} | |
} | |
goto &$real_require; | |
}; | |
{ | |
no strict 'refs'; | |
no warnings 'redefine'; | |
*{'CORE::GLOBAL::require'} = $require; | |
} | |
} | |
sub loaded_by { | |
my $level = 1; | |
while(my @caller = caller($level++)) { | |
next if $caller[0] eq __PACKAGE__; | |
return [$caller[0], $caller[1]]; | |
} | |
return ['', '']; | |
} | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment