He tenido este problema yo mismo. Devel::Modlist (según lo sugerido por this answer) adopta un enfoque dinámico. Informa los módulos que se cargaron realmente durante una ejecución particular de su secuencia de comandos. Esto capta los módulos que se cargan por cualquier medio, pero es posible que no capte los requisitos condicionales. Es decir, si usted tiene un código como éste:
if ($some_condition) { require Some::Module }
y $some_condition
resulta ser falsa, Devel::Modlist
no la lista de Some::Module
como requisito.
Decidí usar Module::ExtractUse en su lugar. Hace un análisis estático, lo que significa que siempre detectará Some::Module
en el ejemplo anterior. Por otro lado, no se puede hacer nada al respecto código como:
my $module = "Other::Module";
eval "use $module;";
Por supuesto, se puede usar ambos enfoques y luego combinar las dos listas.
De todos modos, aquí está la solución que se me ocurrió:
#! /usr/bin/perl
#---------------------------------------------------------------------
# Copyright 2008 Christopher J. Madsen <perl at cjmweb.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the
# GNU General Public License or the Artistic License for more details.
#
# Recursively collect dependencies of Perl scripts
#---------------------------------------------------------------------
use strict;
use warnings;
use File::Spec();
use Module::CoreList();
use Module::ExtractUse();
my %need;
my $core = $Module::CoreList::version{'5.008'};
# These modules have lots of dependencies. I don't need to see them now.
my %noRecurse = map { $_ => 1 } qw(
Log::Log4perl
XML::Twig
);
foreach my $file (@ARGV) {
findDeps($file);
}
foreach my $module (sort keys %need) {
print " $module\n";
}
#---------------------------------------------------------------------
sub findDeps
{
my ($file) = @_;
my $p = Module::ExtractUse->new;
$p->extract_use($file);
foreach my $module ($p->array) {
next if exists $core->{$module};
next if $module =~ /^5[._\d]+/; # Ignore "use MIN-PERL-VERSION"
next if $module =~ /\$/; # Run-time specified module
if (++$need{$module} == 1 and not $noRecurse{$module}) {
my $path = findModule($module);
if ($path) { findDeps($path) }
else { warn "WARNING: Can't find $module\n" }
} # end if first use of $module
} # end foreach $module used
} # end findDeps
#---------------------------------------------------------------------
sub findModule
{
my ($module) = @_;
$module =~ s!::|\'!/!g;
$module .= '.pm';
foreach my $dir (@INC) {
my $path = File::Spec->catfile($dir, $module);
return $path if -f $path;
}
return;
} # end findModule
que había corrido esto como:
perl finddeps.pl scriptToCheck.pl otherScriptToCheck.pl
Se imprime una lista de todos los módulos no esenciales necesarios para ejecutar los scripts listado. (A menos que hagan trucos con la carga del módulo que impiden que Module :: ExtractUse los vea.)
Interesante, pero si trata de usar que, en un entorno comercial en vivo equipo le operaciones va a ser un poco molesto con usted y quiere para ver si conoce los conceptos de estabilidad y seguridad :-) – Vagnerr