Как определить, какой файл Perl загружен при использовании модуля?
в Perl, когда я делаю use <module name> <ver>;
, система находит файл .pm
для библиотеки где-то в пути @INC
.
Есть ли надежный способ загрузки файла?
Ответы
Ответ 1
Да, %INC
содержит полный путь, из которого был загружен модуль.
Пример:
$ perl -M'Data::Dump qw(pp)' -e 'pp(\%INC)'
{
"Data/Dump.pm" => "/usr/share/perl5/Data/Dump.pm",
"Exporter.pm" => "/usr/share/perl/5.10/Exporter.pm",
"List/Util.pm" => "/usr/lib/perl/5.10/List/Util.pm",
"Scalar/Util.pm" => "/usr/lib/perl/5.10/Scalar/Util.pm",
"XSLoader.pm" => "/usr/lib/perl/5.10/XSLoader.pm",
"overload.pm" => "/usr/share/perl/5.10/overload.pm",
"strict.pm" => "/usr/share/perl/5.10/strict.pm",
"vars.pm" => "/usr/share/perl/5.10/vars.pm",
"warnings.pm" => "/usr/share/perl/5.10/warnings.pm",
"warnings/register.pm" => "/usr/share/perl/5.10/warnings/register.pm",
}
Ответ 2
Если модуль имеет документацию pod, и если вы можете гарантировать, что утилита perldoc в вашей PATH принадлежит к тому же perl, который запускает ваш script, то эта команда часто дает вам фактический найденный файл:
perldoc -l ModuleName
Ответ 3
perl -M'LWP '-e' использовать Data:: Dumper; print Dumper\%INC '| grep LWP
Здесь будет указано расположение модуля LWP на диске, а также список модулей, загруженных внутри LWP.
'LWP.pm' => '/usr/lib/perl5/5.10.0/LWP.pm',
'LWP/Protocol.pm' => '/usr/lib/perl5/5.10.0/LWP/Protocol.pm',
'LWP/UserAgent.pm' => '/usr/lib/perl5/5.10.0/LWP/UserAgent.pm',
Ответ 4
Вы хотите посмотреть в переменной %INC
, которая записывает имя файла, которое оно загружает, для загружаемых вами библиотек с do
, require
или use
. Подробнее см. perlvar.
Ответ 5
В CPAN имеется большое количество модулей для поиска этой информации, наиболее вероятными кандидатами являются Module:: Find, Module:: Which и Module:: Locate. Я бы, вероятно, пошел с Module:: Locate:
use strict;
use warnings;
use Module::Locate qw/locate/;
my $to_find = "Some::Module";
print "Perl would use: ", scalar locate($to_find), "\n";
В контексте списка locate возвращает все найденные копии Some:: Module в порядке, основанном на @INC.
Изменить:
derobert предлагает гораздо лучший способ, я не понимал, что% INC уже имеет это... Это решение на основе модулей все равно было бы полезно, если бы вы хотели знать, прежде чем загружать модуль, из которого он будет загружен.
Ответ 6
Вот однострочный (с bash оберткой), чтобы определить, установлен ли модуль, и где он будет загружен из:
#!/bin/bash
perl -M${1} -le "\$mname=\"${1}.pm\";\$mname=~s#::#/#g;print \"$1 INSTALLED AT \$INC{\$mname}\";" 2>/dev/null || echo "${1} NOT INSTALLED"
Назовите его синтаксисом имени модуля perl:
./find_perl_module Font::Metrics::Courier
Ответ 7
Из того, что я нашел, perl будет выглядеть в каталогах внутри пути:
perl -le 'print foreach @INC'
Затем он будет выглядеть в стандартной библиотеке, а затем в текущем каталоге.
Это дает вам порядок поиска.
Мой источник:
Расширение пути к библиотеке
Ответ 8
Module:: Mapper предоставляет способ для навигации по дереву @INC для поиска модулей:
perl -MModule::Mapper -MData::Dumper \
-e 'print Dumper( find_sources( UseINC => 1, Modules => [ @ARGV ] ) )' \
list-of-modules-to-locate
Ответ 9
Вы можете использовать команду instmodsh: http://perldoc.perl.org/instmodsh.html.
Ответ 10
Я использую оболочку script/usr/local/bin/which_perl_module
#!/bin/sh
if [ ! $1 ];then echo "Which perl module should I look for?"; exit; fi
echo -n "You are using: "
perldoc -l $1
echo "which I found by looking in:"
perl -MData::Dump=pp -e 'unshift @INC, '$1'; pp(\@INC)'