«Использование пакетов на основе Moose в сценариях Perl

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

Моя проблема довольно проста.

История:

  1. Я сделал пакет и использовал Moose для ООП.
  2. Я сохранил пакет My::FileIO в домашнем каталоге в общем каталоге для всех таких пользовательских модулей в форме /home/USER/DIRECTORY/My/FileIO.pm. Фактически, это было сделано после того, как я использовал Module::Starter и использовал perl Makefile.PL, который установил его в этом формате.
  3. Я использовал внешний скрипт для тестирования модуля. В этом я использовал use lib '/home/USER/DIRECTORY/', а затем подтвердил наличие модуля, проверив %INC, что дало правильное значение имени файла. Это привело меня к выводу, что Perl загрузил модуль без каких-либо жалоб.
  4. Я пытался использовать этот модуль My::FileIO, и скрипт тестирования в то время также не жаловался.
  5. Сценарий тестирования не удался после того, как я использовал конструктор по-лосячьи, my $test = My::FileIO->new() и вот что он выдал - Can't locate object method "new" via package "My::FileIO" (perhaps you forgot to load "My::FileIO"?) at line 1.
  6. Я попытался создать фиктивную подпрограмму с именем init, но она тоже не удалась.
  7. Однако автору Perl Maven удалось использовать эти коды (https://perlmaven.com/object-Oriented-perl-using-moose)

Его тестовый сценарий

use strict;
use warnings;
use v5.10;

use Person;

my $teacher = Person->new( name => 'Joe' );
say $teacher->name;

Его тестовый модуль

package Person;
use Moose;

has 'name' => (is => 'rw');

1;

Резюме:

  1. Сценарий тестирования может успешно загрузить модуль.
  2. Я вообще не могу пользоваться пакетом.

Это предполагаемый FileIO.pm

package My::FileIO; 
use feature 'state'; 
use List::Util qw(max); 
use Data::Dumper; 
use Moose;
use Type::Params qw(compile);
use Type::Utils; 
use Types::Standard qw(Str FileHandle Int HashRef ArrayRef Maybe);

[ ALL THE CODE ]

1;

Полный код находится по адресу https://pastebin.com/1kxiPazd.

Это мой тестовый файл - test.pl

use lib '/home/USER/DIRECTORY';
use My::FileIO; 

$test = My::FileIO->new() # Fails 

Что я делаю не так? Я сделал фиктивный модуль, такой как Perl Maven, и попытался его протестировать, но он тоже не удался.

Обновление - прошу прощения за глупые ошибки в моей записи.


person user9111001    schedule 10.10.2020    source источник
comment
Если он терпит неудачу в new, а не в use, он находит файл в порядке. Вы уверены, что имя пакета My::FileIO, имя файла My/FileIO.pm и имя класса, для которого вы вызываете new, правильно совпадают? Включая различия с прописными и строчными буквами?   -  person tobyink    schedule 11.10.2020
comment
Совет: если у вас есть центральное расположение, в которое вы устанавливаете модули (например, /home/USER/DIRECTORY), более разумно использовать env var PERL5LIB (export PERL5LIB=/home/USER/DIRECTORY), чем использовать use lib.   -  person ikegami    schedule 11.10.2020
comment
Я вставил заголовок фактического кода. Путь FileIO.Pm — /home/USER/DIRECTORY/My/FileIO.pm, содержащий класс My::FileIO.   -  person user9111001    schedule 11.10.2020
comment
@user9111001 user9111001 да, но сообщение об ошибке, которое вы получили, это Can't locate object method "new" via package "My::Test" (perhaps you forgot to load "My::Test"?) at line 1., которое ссылается на совершенно другое имя класса (My::Test вместо My::FileIO), поэтому я не уверен, что вы используете правильное имя класса.   -  person tobyink    schedule 11.10.2020
comment
Кроме того, проверяя свой полный код, вы, кажется, часто делаете это: state $check = compile($sometype); my $somevar = shift; $check->($mode); но вы можете просто сделать это: my $somevar = $sometype->(shift); и это будет намного быстрее. compile предназначен для создания проверки для проверки всего @_ сразу; это мега-излишняя проверка только одной переменной.   -  person tobyink    schedule 11.10.2020
comment
@тобайнк. Вы подняли правильный вопрос. Я делал это немного идиоматически, как показано в документе.   -  person user9111001    schedule 11.10.2020
comment
Итак... Скопировал ваш модуль по ссылке. Имя пакета My::FH. Я создал каталог с именем My и поместил в него этот файл с именем FH.pm. Когда я загружаю этот модуль (use My::FH;) и создаю объект, он работает без проблем. Я не знаю, в чем вы ошибаетесь, но, скорее всего, это касается именования и размещения. Возможно, см. этот пост   -  person zdim    schedule 11.10.2020
comment
Примечания к приведенному выше комментарию: (1) Чтобы загрузить модуль, помещенный в каталог, который находится в каталоге скрипта, вы должны указать Perl, чтобы он также выполнял поиск в каталоге скрипта (по умолчанию в современном Perl это не выполняется). версии). Лучший способ: use FindBin qw($RealBin); use lib $RealBin;. Теперь вы можете сказать use My::FH; (если в каталоге вашего скрипта есть каталог My, а в нем FH.pm). (2) Чтобы создать объект в этом модуле, вам нужно My::FH->new(filename => valid_file_name);. Поэтому вы должны указать допустимое имя файла (такой файл должен существовать)   -  person zdim    schedule 11.10.2020
comment
@user9111001 user9111001 Я написал документ :)   -  person tobyink    schedule 15.10.2020


Ответы (1)


То, что вы разместили внизу, будет работать, если полный путь к файлу, который вы назвали FileIO.pm, равен /home/USER/DIRECTORY/My/FileIO.pm.

Код, который вы разместили внизу, явно не тот, который вы использовали в своем тесте, вызвавшем ошибку. В предоставленном вами сообщении об ошибке говорилось, что вы использовали -e, а не test.pl, и говорилось, что вы пытались создать объект класса My::Test, а не My::FileIO.

person ikegami    schedule 11.10.2020
comment
Я извиняюсь за это. Однако он действует аналогично, если не используется -e. - person user9111001; 11.10.2020
comment
Не стесняйтесь, дайте мне знать, когда вы исправите вопрос. Он по-прежнему не содержит кода, который вы на самом деле запустили. В качестве альтернативы предоставьте (неотредактированный) вывод cat test.pl; cat /home/USER/DIRECTORY/My/FileIO.pm; ./test.pl - person ikegami; 11.10.2020
comment
Вы можете проверить полный код @ikegami. - person user9111001; 11.10.2020
comment
Вы еще не опубликовали демонстрацию проблемы (минимальную или нет). И вы уже знаете, как решить вашу проблему: используйте код, который вы разместили внизу своего ответа. Я не могу сказать, что вы сделали не так, потому что 1) слишком много противоречивой информации о том, какой код вы на самом деле запустили, и 2) вы даже не предоставили полученное сообщение об ошибке. Я не уверен, что еще вы хотите. - person ikegami; 11.10.2020