如何查看特定 Perl 模块需要的所有模块?
How can I see all modules that a specific Perl module requires?
假设我得到了一个像 Data::Validate::IP
这样的模块,我想查看它需要的所有模块 (use
s),我该怎么做呢?我正在寻找审核模块的依赖项。
进口追踪
您可以使用 Devel::TraceUse
查看相关模块使用的所有模块,
perl -d:TraceUse -MData::Validate::IP -e1
请注意,它只测试编译时包含的内容,要查看它可能使用 require
等引入的所有代码,请实际尝试 运行 代码,
perl -d:TraceUse -MData::Validate::IP -e'Data::Validate::IP::is_ipv4("1.2.3.4")'
示例输出
Modules used from -e:
1. Data::Validate::IP 0.27, -e line 0 [main]
2. strict 1.11, Data/Validate/IP.pm line 3
3. warnings 1.47, Data/Validate/IP.pm line 4
4. NetAddr::IP 4.079, Data/Validate/IP.pm line 10
5. Carp 1.50, NetAddr/IP.pm line 7
6. overloading 0.02, Carp.pm line 170
7. Exporter 5.74, Carp.pm line 224
18. Exporter::Heavy 5.74, Exporter.pm line 16
8. NetAddr::IP::Lite 1.57, NetAddr/IP.pm line 8
9. NetAddr::IP::InetBase 0.08, NetAddr/IP/Lite.pm line 17
10. vars 1.05, NetAddr/IP/InetBase.pm line 8
11. warnings::register 1.04, vars.pm line 7
12. AutoLoader 5.74, NetAddr/IP/InetBase.pm line 9
15. auto/NetAddr/IP/InetBase/AF_INET6.al, AutoLoader.pm line 34 (FAILED)
13. Socket 2.029, NetAddr/IP/InetBase.pm line 77
14. XSLoader 0.30, Socket.pm line 701
16. Socket6 0.29, NetAddr/IP/InetBase.pm line 85
17. base 2.27, Socket6.pm line 215
19. NetAddr::IP::Util 1.53, NetAddr/IP/Lite.pm line 31
20. NetAddr::IP::Util_IS 1, NetAddr/IP/Util.pm line 10
21. overload 1.31, NetAddr/IP/Lite.pm line 280
22. Scalar::Util 1.55, Data/Validate/IP.pm line 11
23. List::Util 1.55, Scalar/Util.pm line 23
Modules used, but not reported:
/usr/local/cpanel/3rdparty/perl/532/lib/perl5/cpanel_lib/x86_64-linux-64int/auto/NetAddr/IP/InetBase/autosplit.ix
/usr/local/cpanel/3rdparty/perl/532/lib/perl5/cpanel_lib/x86_64-linux-64int/auto/NetAddr/IP/InetBase/inet_any2n.al
/usr/local/cpanel/3rdparty/perl/532/lib/perl5/cpanel_lib/x86_64-linux-64int/auto/NetAddr/IP/InetBase/ipv6_aton.al
/usr/local/cpanel/3rdparty/perl/532/lib/perl5/cpanel_lib/x86_64-linux-64int/auto/NetAddr/IP/Util/autosplit.ix
/usr/local/cpanel/3rdparty/perl/532/lib/perl5/cpanel_lib/x86_64-linux-64int/auto/NetAddr/IP/autosplit.ix
这些服务可以向您显示已声明的依赖项:
MetaCPAN 显示模块的依赖列表。它还显示“反向依赖关系”,因此您可以看到什么使用了模块。
CPAN Dependency Graphs 将以图像形式显示依赖信息。
我经常查看 %INC
的结果,它显示了加载的内容(但不显示由谁加载)。这在尝试获得 100% 的测试覆盖率以了解您获得了大部分内容时非常方便。但是,除非代码使用它们,否则这仍然不会选择可选或动态模块。
CPAN::Dependencies 中的 cpandeps
工具也很方便:
$ cpandeps Business::ISBN
Business::ISBN (dist: B/BD/BDFOY/Business-ISBN-3.006.tar.gz)
Business::ISBN::Data (dist: B/BD/BDFOY/Business-ISBN-Data-20210112.006.tar.gz)
Carp (dist: X/XS/XSAWYERX/Carp-1.50.tar.gz)
Exporter (dist: T/TO/TODDR/Exporter-5.74.tar.gz)
IPC::Open3 (dist: S/SH/SHAY/perl-5.32.1.tar.gz)
Test::More (dist: E/EX/EXODIST/Test-Simple-1.302183.tar.gz)
File::Temp (dist: E/ET/ETHER/File-Temp-0.2311.tar.gz)
File::Path (dist: J/JK/JKEENAN/File-Path-2.18.tar.gz)
File::Spec::Functions (dist: X/XS/XSAWYERX/PathTools-3.75.tar.gz)
Scalar::Util (dist: P/PE/PEVANS/Scalar-List-Utils-1.55.tar.gz)
parent (dist: C/CO/CORION/parent-0.238.tar.gz)
Storable (dist: X/XS/XSAWYERX/Storable-3.15.tar.gz)
XSLoader (dist: S/SA/SAPER/XSLoader-0.24.tar.gz)
ExtUtils::MakeMaker (dist: B/BI/BINGOS/ExtUtils-MakeMaker-7.60.tar.gz)
Encode (dist: D/DA/DANKOGAI/Encode-3.08.tar.gz)
Pod::Man (dist: R/RR/RRA/podlators-4.14.tar.gz)
Pod::Simple (dist: K/KH/KHW/Pod-Simple-3.42.tar.gz)
Pod::Escapes (dist: N/NE/NEILB/Pod-Escapes-1.07.tar.gz)
Test (dist: J/JE/JESSE/Test-1.26.tar.gz)
Text::Wrap (dist: M/MU/MUIR/modules/Text-Tabs+Wrap-2013.0523.tar.gz)
if (dist: X/XS/XSAWYERX/if-0.0608.tar.gz)
还有各种静态分析工具:
我写了 Module::Extract::Use 来提取在特定情况下出现的名称空间(use
、require
、base
、parent
).字面裸词需要在那里。
MetaCPAN::Client and Module::CoreList可以通过多种方式配置信息。在这里,我得到了所有不是 perl 本身的运行时依赖项,也不是核心模块。不过,您可以过滤其他内容:
use v5.10;
use MetaCPAN::Client;
use Module::CoreList;
my $metacpan = MetaCPAN::Client->new;
my @queue = map { [ 0, $_ ] } @ARGV;
while( my $tuple = shift @queue ) {
state %Seen;
my $release = eval { $metacpan->release( $tuple->[1] =~ s/::/-/gr ) };
next unless $release;
say "\t" x $tuple->[0], $release->distribution,
defined $tuple->[2] ? " $tuple->[2]" : '';
push @queue,
map { [ $tuple->[0] + 1, $_->{module}, $_->{version} ] }
grep { $_->{module} ne 'perl' }
grep { $_->{phase} eq 'runtime' }
grep { ! Module::CoreList::is_core( $_->{module}, undef, $^V ) }
grep { ! $Seen{ $_->{module} }++ }
$release->dependency->@*;
}
假设我得到了一个像 Data::Validate::IP
这样的模块,我想查看它需要的所有模块 (use
s),我该怎么做呢?我正在寻找审核模块的依赖项。
进口追踪
您可以使用 Devel::TraceUse
查看相关模块使用的所有模块,
perl -d:TraceUse -MData::Validate::IP -e1
请注意,它只测试编译时包含的内容,要查看它可能使用 require
等引入的所有代码,请实际尝试 运行 代码,
perl -d:TraceUse -MData::Validate::IP -e'Data::Validate::IP::is_ipv4("1.2.3.4")'
示例输出
Modules used from -e:
1. Data::Validate::IP 0.27, -e line 0 [main]
2. strict 1.11, Data/Validate/IP.pm line 3
3. warnings 1.47, Data/Validate/IP.pm line 4
4. NetAddr::IP 4.079, Data/Validate/IP.pm line 10
5. Carp 1.50, NetAddr/IP.pm line 7
6. overloading 0.02, Carp.pm line 170
7. Exporter 5.74, Carp.pm line 224
18. Exporter::Heavy 5.74, Exporter.pm line 16
8. NetAddr::IP::Lite 1.57, NetAddr/IP.pm line 8
9. NetAddr::IP::InetBase 0.08, NetAddr/IP/Lite.pm line 17
10. vars 1.05, NetAddr/IP/InetBase.pm line 8
11. warnings::register 1.04, vars.pm line 7
12. AutoLoader 5.74, NetAddr/IP/InetBase.pm line 9
15. auto/NetAddr/IP/InetBase/AF_INET6.al, AutoLoader.pm line 34 (FAILED)
13. Socket 2.029, NetAddr/IP/InetBase.pm line 77
14. XSLoader 0.30, Socket.pm line 701
16. Socket6 0.29, NetAddr/IP/InetBase.pm line 85
17. base 2.27, Socket6.pm line 215
19. NetAddr::IP::Util 1.53, NetAddr/IP/Lite.pm line 31
20. NetAddr::IP::Util_IS 1, NetAddr/IP/Util.pm line 10
21. overload 1.31, NetAddr/IP/Lite.pm line 280
22. Scalar::Util 1.55, Data/Validate/IP.pm line 11
23. List::Util 1.55, Scalar/Util.pm line 23
Modules used, but not reported:
/usr/local/cpanel/3rdparty/perl/532/lib/perl5/cpanel_lib/x86_64-linux-64int/auto/NetAddr/IP/InetBase/autosplit.ix
/usr/local/cpanel/3rdparty/perl/532/lib/perl5/cpanel_lib/x86_64-linux-64int/auto/NetAddr/IP/InetBase/inet_any2n.al
/usr/local/cpanel/3rdparty/perl/532/lib/perl5/cpanel_lib/x86_64-linux-64int/auto/NetAddr/IP/InetBase/ipv6_aton.al
/usr/local/cpanel/3rdparty/perl/532/lib/perl5/cpanel_lib/x86_64-linux-64int/auto/NetAddr/IP/Util/autosplit.ix
/usr/local/cpanel/3rdparty/perl/532/lib/perl5/cpanel_lib/x86_64-linux-64int/auto/NetAddr/IP/autosplit.ix
这些服务可以向您显示已声明的依赖项:
MetaCPAN 显示模块的依赖列表。它还显示“反向依赖关系”,因此您可以看到什么使用了模块。
CPAN Dependency Graphs 将以图像形式显示依赖信息。
我经常查看
%INC
的结果,它显示了加载的内容(但不显示由谁加载)。这在尝试获得 100% 的测试覆盖率以了解您获得了大部分内容时非常方便。但是,除非代码使用它们,否则这仍然不会选择可选或动态模块。
CPAN::Dependencies 中的 cpandeps
工具也很方便:
$ cpandeps Business::ISBN
Business::ISBN (dist: B/BD/BDFOY/Business-ISBN-3.006.tar.gz)
Business::ISBN::Data (dist: B/BD/BDFOY/Business-ISBN-Data-20210112.006.tar.gz)
Carp (dist: X/XS/XSAWYERX/Carp-1.50.tar.gz)
Exporter (dist: T/TO/TODDR/Exporter-5.74.tar.gz)
IPC::Open3 (dist: S/SH/SHAY/perl-5.32.1.tar.gz)
Test::More (dist: E/EX/EXODIST/Test-Simple-1.302183.tar.gz)
File::Temp (dist: E/ET/ETHER/File-Temp-0.2311.tar.gz)
File::Path (dist: J/JK/JKEENAN/File-Path-2.18.tar.gz)
File::Spec::Functions (dist: X/XS/XSAWYERX/PathTools-3.75.tar.gz)
Scalar::Util (dist: P/PE/PEVANS/Scalar-List-Utils-1.55.tar.gz)
parent (dist: C/CO/CORION/parent-0.238.tar.gz)
Storable (dist: X/XS/XSAWYERX/Storable-3.15.tar.gz)
XSLoader (dist: S/SA/SAPER/XSLoader-0.24.tar.gz)
ExtUtils::MakeMaker (dist: B/BI/BINGOS/ExtUtils-MakeMaker-7.60.tar.gz)
Encode (dist: D/DA/DANKOGAI/Encode-3.08.tar.gz)
Pod::Man (dist: R/RR/RRA/podlators-4.14.tar.gz)
Pod::Simple (dist: K/KH/KHW/Pod-Simple-3.42.tar.gz)
Pod::Escapes (dist: N/NE/NEILB/Pod-Escapes-1.07.tar.gz)
Test (dist: J/JE/JESSE/Test-1.26.tar.gz)
Text::Wrap (dist: M/MU/MUIR/modules/Text-Tabs+Wrap-2013.0523.tar.gz)
if (dist: X/XS/XSAWYERX/if-0.0608.tar.gz)
还有各种静态分析工具:
我写了 Module::Extract::Use 来提取在特定情况下出现的名称空间(
use
、require
、base
、parent
).字面裸词需要在那里。MetaCPAN::Client and Module::CoreList可以通过多种方式配置信息。在这里,我得到了所有不是 perl 本身的运行时依赖项,也不是核心模块。不过,您可以过滤其他内容:
use v5.10;
use MetaCPAN::Client;
use Module::CoreList;
my $metacpan = MetaCPAN::Client->new;
my @queue = map { [ 0, $_ ] } @ARGV;
while( my $tuple = shift @queue ) {
state %Seen;
my $release = eval { $metacpan->release( $tuple->[1] =~ s/::/-/gr ) };
next unless $release;
say "\t" x $tuple->[0], $release->distribution,
defined $tuple->[2] ? " $tuple->[2]" : '';
push @queue,
map { [ $tuple->[0] + 1, $_->{module}, $_->{version} ] }
grep { $_->{module} ne 'perl' }
grep { $_->{phase} eq 'runtime' }
grep { ! Module::CoreList::is_core( $_->{module}, undef, $^V ) }
grep { ! $Seen{ $_->{module} }++ }
$release->dependency->@*;
}