Почему мой сценарий Perl не находит мой модуль даже после того, как я настроил @INC с помощью FindBin?

Я хочу иметь возможность использовать модуль, хранящийся в каталоге lib моего репозитория исходного кода, и я хочу, чтобы единственным условием для использования разработчиком написанных мной сценариев было наличие стандарта. Установка Perl, но я не уверен, как это сделать.

В моих сценариях у меня есть

use FindBin qw($Bin);
use lib "$Bin/lib"; # store non standard modules here
use Term::ANSIColor;
use Win32::Console::ANSI;
print Term::ANSIColor::colored("this should be in color\n", "bold red");

и я поместил модуль в ./lib. Я проверил, что это фактическое место, где находится модуль (переименовав его и вызвав сбой). Однако, даже если модуль находится в произвольном каталоге lib, по-прежнему требуется, чтобы ppm знал о модуле.

Я не могу заставить свои скрипты найти/использовать его в lib без предварительной установки ppm. Я бы предположил, что должен быть какой-то способ обойти это.

Я знаю, что это может быть нетипичный запрос, но мои цели, вероятно, нетипичны. Я просто хочу, чтобы разработчик выполнил проверку и сразу же использовал некоторые сценарии без необходимости запуска каких-либо дополнительных команд или использования диспетчера пакетов.

Спасибо за любое понимание.

EDIT: я обновил полный пример. Я также понял, что если я удалю его через ppm (но оставлю pm в указанном каталоге), мне, возможно, придется изменить свой синтаксис, и я не рассматривал это раньше. Так что, возможно, мне нужно указать полный путь или использовать запрос, например jheddings или предложение BipedalShark (т.е. если он не установлен, то я должен использовать требование и добавить к нему .pm или использовать блок BEGIN.

Если это так, то я не нашел правильный синтаксис.

EDIT 2: Основываясь на комментарии ниже, я понимаю, что у меня может быть ошибочное предположение. Я рассуждаю так: если я напрямую ссылаюсь на фактический код, .pm, то я должен иметь возможность использовать его без использования менеджера пакетов. Может быть, это не так, или если я хочу сделать это, возможно, я должен сделать это по-другому. В качестве альтернативы мне, возможно, придется реорганизовать код в файле .pm.

EDIT 3: я думаю, что неправильно понял несколько вещей. Сообщение об ошибке в моей компиляции IDE не удалось потребовать, это выделение строки, которую я использовал для включения модуля, и сообщение об ошибке консоли Не удается найти загружаемый объект для модуля Win32::Console::ANSI

Я читал это как проблему с загрузкой самого модуля, но, похоже, это проблема, возникающая из-за того, что сам модуль пытается загрузить. Интересно, что это проблема только потому, что я не использовал установку ppm.

Он находит фактический модуль. Я смог убедиться в этом, закомментировав проблемные строки.

Спасибо за помощь, но мне придется потратить на это еще немного времени.


person Keith Bentrup    schedule 15.11.2009    source источник
comment
Ваш вопрос не имеет смысла. PPM ни на что не влияет, кроме как в качестве установщика. Что он делает, когда не работает?   -  person hobbs    schedule 15.11.2009
comment
Почему вы говорите о пакетных менеджерах? Ваш скрипт не должен заботиться о том, как туда попал модуль. Ваш реальный вопрос отличается от того, что вы опубликовали?   -  person brian d foy    schedule 15.11.2009
comment
Какой модуль находится в lib/? Как выглядит lib/?   -  person brian d foy    schedule 15.11.2009
comment
ИМХО, вы можете использовать PAR и скомпилировать его в .exe.   -  person Alexandr Ciornii    schedule 15.11.2009
comment
@Кит: какие-нибудь обновления? ты нашел проблему?   -  person Ether    schedule 17.11.2009
comment
Еще раз спасибо за помощь. См. мою заметку ниже принятого ответа. Извините за задержку с возвратом. Сейчас я могу играть с Perl только по выходным.   -  person Keith Bentrup    schedule 22.11.2009
comment
Милая, я рада, что ты нашел проблему!   -  person Ether    schedule 22.11.2009


Ответы (5)


См. perldoc perldiag в разделе "Не удается найти загружаемый объект для модуля...":

    (F) The module you loaded is trying to load an external library,
    like for example, "foo.so" or "bar.dll", but the DynaLoader module
    was unable to locate this library.  See DynaLoader.

Вы правы в том, что эта проблема возникает из-за того, что модуль пытается загрузить что-то Dynaloader делает. Однако документация для Win32: :Console::ANSI не упоминает никаких требований к внешним библиотекам.

person Ether    schedule 15.11.2009
comment
Когда я запустил ppm, установите bribes.org/perl/ppm/Win32-Console -ANSI.ppd, он также установил dll в C:\Perl\site\lib\auto\Win32\Console\ANSI, о котором я не знал, и привел меня по этому пути. Я думал, что pm был единственной загрузкой, отсюда и вся путаница. - person Keith Bentrup; 22.11.2009

Сохраняете ли вы структуру пути модуля в каталоге lib?
т. е. ваш модуль должен находиться в пути $Bin/lib/Some/Module.pm.

person jheddings    schedule 15.11.2009
comment
Да, это то, что я имею в виду, что я могу переименовать его и вызвать сбой. Я уверен, что файл в пути к библиотеке - это тот, который он использует. Спасибо. - person Keith Bentrup; 15.11.2009
comment
Теперь я понял, что мне, возможно, придется изменить свой синтаксис, если он не установлен через ppm. Я пробовал требовать, использовать и блок Begin, указывающий как относительный, так и абсолютный путь, но пока не нашел решения. - person Keith Bentrup; 15.11.2009

Из ответа perlfaq8 на Как добавить каталог, в котором находится моя программа, в путь поиска модуля/библиотеки?

Похоже, вы делаете это правильно, но вам нужно дать нам больше, если вы рассчитываете получить помощь.

Когда вы запускаете этот скрипт, что заканчивается @INC? Поместите строку отладки, например:

 BEGIN {
      use lib ...;
      print "INC is \@INC\n"; 
      }

Убедитесь, что этот вывод показывает ожидаемый каталог. Если это не так, начните разделять проблему пополам оттуда.

person brian d foy    schedule 15.11.2009

Попробуй это:

BEGIN {
    use FindBin qw($Bin);
}
use lib "$Bin/lib"; # store non standard modules here
person Helter    schedule 20.09.2010

Я все время устанавливаю модули вручную, и, похоже, это работает. Я просто копирую каталоги и файлы в определенное место и использую директиву «use lib», как вы показали. Иногда я пропускаю файл и получаю ошибку времени выполнения, что он ищет определенный файл, и я нахожу файл в Интернете, помещаю его в нужное место, и он работает. Не уверен, что происходит с вашей настройкой. Это должно работать.

Обычно я помещаю модули Perl в тот же каталог, что и мой скрипт, а затем: использую lib "." Но я не знаю, будет ли это иметь значение.

person Kurt W. Leucht    schedule 15.11.2009