Обязательно ли наличие папки по имени пакета для создания пакета?
Вопрос
Мы выделяем общий код из нашего проекта Perl.Одну основную программу следует разбить на несколько повторно используемых модулей.
Название нашей программы validate_results.pl
который содержит набор команд проверки.Мы планируем разделить это на небольшие модули, чтобы validate_results.pl
должно быть так:
use Common::Validate_Results;
use Common::Validate_Results::CommonCommands;
use Common::Validate_Results::ReturnCodeValidation;
...
Насколько я понимаю, я должен создать общую папку и под ней Validate_Results.pm
должно присутствовать.Опять под Common
, Validate_Results
папка должна быть создана и под ней CommonCommands
и ReturnCodeValidation
папки должны присутствовать.
Обязательно ли наличие всех этих папок или мы можем разместить все программы Perl в одной папке и логически сгруппировать их и при этом использовать описанный выше способ доступа к модулям (скажем, использовать common::validate_results
как это).
Решение
Иерархия файловой системы обязательна. A :: B :: C всегда будет находиться в A / B / C.pm, где-то в @INC.
Если у вас есть , чтобы обойти это, прочитайте perldoc -f require , в частности, ищите раздел о ссылках на подпрограммы в @INC. Да, вы можете заставить загрузчик модулей делать странные вещи, если вы действительно этого хотите; но это не то, что вы хотите, поверьте мне. Просто придерживайтесь соглашения, как и другие 99,999999% приложений Perl.
Другие советы
Если вы хотите «использовать» свои модули, вы должны соответствовать их структуре.Если вы хотите обойти это, вы можете вместо этого «затребовать» свои модули, передав имя файла require.
Хотя вам действительно не следует этого делать.Если вы действительно не хотите иметь структуру каталогов, удалите ее из имен модулей (хотя это может привести к проблемам в будущем, если у вас когда-нибудь имя модуля будет конфликтовать с чем-то более общим из CPAN).Просто добавьте каталог сценариев в путь INC через Find::Bin и используйте модули напрямую:
use FindBin;
use lib $FindBin::Bin;
use ValidateResults;
use CommonCommands;
use ReturnCodeValidation;
ХТХ
Вот пример модуля и его подмодулей в одном файле:
package Foo;
use strict;
use Exporter 'import';
our @EXPORT = ( 'from_foo' );
sub from_foo { print "from_foo\n"; }
package Foo::Bar;
use strict;
use Exporter 'import';
our @EXPORT = ( 'from_foo_bar' );
sub from_foo_bar { print "from_foo_bar\n"; }
1;
Если в вашей программе вы используете модуль Foo (с файлом .pm):
use Foo;
У вас будет доступ к функциям Foo :: Bar , кроме как в качестве канонических имен (Foo :: Bar :: from_foo_bar). Вы можете импортировать их так:
use Foo;
Foo::Bar->import;
Обратите внимание, что вы не можете сделать это:
use Foo::Bar;
Потому что нет файла Foo / Bar.pm .
Имя пакета в команде 'use' - это просто путь, который заканчивается файлом .pm, поэтому вам не нужна папка с именем каждого пакета. В вашем примере вам нужны папки:
Common
Common/Validate_Results
Но вам не нужны папки:
Common/Validate_Results/CommonCommands
Common/Validate_Results/ReturnCodeValidation
Фактическое имя пакета в .pm-файле не обязательно должно совпадать с именем в команде use, которая его загружает. Но держать пути в соответствии с именами пакетов - это всегда хорошая идея.