Добавить модуль Perl относительно скрипта - PullRequest
2 голосов
/ 15 февраля 2012

я пытаюсь добавить модуль File-Copy-Recursive в мой скрипт, как я уже сделал с другим модулем, но когда я пытаюсь использовать его, я получаю ошибку, которую не могу объяснить:

use lib "./cpan";
use Recursive qw(dircopy);
dircopy($path1, $path2);

ошибка, которую я получаю: Неопределенная подпрограмма & main :: dircopy вызывается в ...

Я не понимаю, модуль явно содержит функцию dircopy.

Ответы [ 3 ]

4 голосов
/ 15 февраля 2012

Как уже говорилось в других ответах, это не работает, потому что вы переместили расположение модуля в каталоге включения с File/Copy/Recursive.pm на Recursive.pm.

Вот почему это не работает:

модуль Perl (файл с расширением .pm) и пакет Perl (коллекция кода в определенном пространстве имен)это две совершенно разные вещи.Обычно мы помещаем пакет в модуль, который имеет одно и то же имя, но на самом деле это просто, чтобы помочь нам, людям, сохранить наше здравомыслие.perl не имеет значения, так или иначе - один модуль может содержать несколько пакетов, один пакет может быть разбит на несколько файлов, а имена пакетов и модулей могут быть совершенно не связаны для всех perl забот.

Но, тем не менее ... существует соглашение об использовании одного и того же имени для обоих, которое команда use использует, чтобы сделать вещи немного более удобными.За кулисами use Module; означает require Module.pm; Module->import; - обратите внимание, что он вызывает импорт для имени модуля , а не имени пакета, содержащегося в модуле!

И это ключ кваша проблема.Даже если вы переместили файл из каталога File/Copy/, его содержимое по-прежнему указывает package File::Copy::Recursive, поэтому на этом весь его код заканчивается.use Recursive пытается вызвать Recursive->import, которого не существует, поэтому ничего не импортируется.Функция dircopy будет импортирована File::Copy::Recursive->import, но она никогда не будет вызвана.

Итак, да.Переместите ./cpan/Recursive.pm в ./cpan/File/Copy/Recursive.pm, чтобы имя пакета и имя модуля снова совпали, и рассудок был восстановлен.(Если вы обращали внимание, у вас должно быть в наличии как минимум два или три других способа заставить это работать, но перемещение файла в нужное место под ./cpan действительно является вашим лучшим вариантом, если вам нужнохраните исходный код File::Copy::Recursive в подкаталоге кода вашего проекта.)

2 голосов
/ 15 февраля 2012

Используйте FindBin для относительного пути к библиотеке:

use FindBin;
use lib "$FindBin::Bin/./cpan";
use File::Copy::Recursive;

И вы должны держать все дерево в ./cpan, и строка использования должна оставаться неизменной.

Файлыпод ./cpan dir:

 find ./cpan/
 ./cpan/File/Copy/Recursive.pm
1 голос
/ 15 февраля 2012

Имя модуля в Perl происходит не только из пути, но и из его объявления package. Вы установили модуль на ./cpan, но указанное имя пакета по-прежнему File::Copy::Recursive.

...