Как я могу получить список модулей, необходимых для пакета? - PullRequest
0 голосов
/ 26 сентября 2018

Я пишу расширение для системы классов Mo * se, и мне нужно получить список, изнутри пакета, всех модулей, требуемых пакетом, используя инструкцию "use".Я попытался проверить структуру данных% INC, но я получил список ВСЕХ модулей, загруженных во время компиляции, и я не могу отфильтровать модули, загруженные моим пакетом.Я предполагаю, что должен иметь дело с отладчиком Perl, но любые предложения будут по достоинству оценены: -)

Например:

package MyApp 0.001 ;
use Module1 ;
use Module2 ;
...
sub list_requested_modules {
    ...HOW TO DO IT ???
}

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Другой вариант, если вы только заинтересованы в том, чтобы знать, какие модули будет загружен / загружен текущим файлом, это будет PPI :

use warnings;
use strict;

use Data::Dumper;
use PPI;
require Mock::Sub;

my $ppi_doc  = PPI::Document->new(__FILE__);
my $ppi_deps = $ppi_doc->find('PPI::Statement::Include');

for (@$ppi_deps){
    print $_->module . "\n";
}

Вывод:

warnings
strict
Data::Dumper
PPI
Mock::Sub
0 голосов
/ 26 сентября 2018

Вы не можете различить модули, загруженные в текущий файл, и модули, которые уже были загружены.Подумайте, есть ли у вас «use Module1;»но Module1 уже был загружен, поэтому все, что он делает, это импортирует в текущий пакет из уже загруженного модуля.С чего бы вы тогда посчитали, что модуль был загружен?

В зависимости от того, что вы пытаетесь выяснить, вы можете сделать две вещи: вы можете проанализировать файл, чтобы угадать, какие модули ему нужны (хотя это не гарантирует ихбудет загружен оттуда, они могут быть уже загружены, как я упоминал ранее).Хороший инструмент для этого - Perl :: PrereqScanner :: Lite .Вы можете использовать литерал __FILE__ для получения имени текущего файла.

use Perl::PrereqScanner::Lite;
my @required = Perl::PrereqScanner::Lite->new->scan_file(__FILE__)->required_modules;

Другой вариант - отслеживать, какие модули загружаются самостоятельно.В самом начале файла поместите это:

my %original_inc;
BEGIN { %original_inc = %INC }

Затем, либо сразу после этого, чтобы найти любые модули, загруженные во время компиляции (включая операторы use), или в более поздней подпрограмме, вы можете сравнить, как% INC изменено:

my @newly_loaded = grep { !exists $original_inc{$_} } keys %INC;

В дополнение к ранее упомянутому предупреждению о том, что модули, возможно, уже были ранее необходимы и, таким образом, уже присутствуют в% INC, загружаемые вами модули могут загружать другие модули по очереди, поэтому разницавероятно, не будет точно совпадать с тем, что use операторов в файле.

РЕДАКТИРОВАТЬ: Лично я бы избежать обоих этих методов, устраняя необходимость в такой логике в первую очередь.Вместо того, чтобы загружать свои модули с помощью use, напишите подпрограмму, которая загружает их с помощью Module :: Runtime и отслеживает то, что вы загружаете с ним тем или иным способом, и вызываете это для каждого модуля в блоке BEGIN,Но учтите, что это повредит автоматическому сканированию prereq, такому как модуль PrereqScanner, о котором я упоминал выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...