От всего я читал при использовании модулей Perl, основное использование:
.pm
расширение, которое включает оператор package <name>
, где <name>
имя файла модуля без расширения.use <name>;
.Приложение, которое я кодирую, имеет один основной сценарий кода, который использует приблизительно 5 модулей. Я забыл включать package <name>
оператор в модулях, но мой код все еще работал очень хорошо с use <name>
оператор. Я начал получать Undefined subroutine
ошибки с одним из модулей, таким образом, я добавил оператор пакета к каждому из модулей. Теперь остальная часть тех модулей прекратила работать. Что дает?
Пример:
mainapp.pl
#!/usr/bin/perl
use UtyDate;
my $rowDate = CurrentDate("YYYYMMDD");
UtyDate.pm
#!/usr/bin/perl
package UtyDate;
sub CurrentDate
{
#logic
}
return 1;
Когда я выполняю вышеупомянутый код, я получаю ошибку Undefined subroutine &main::CurrentDate called at...
. Однако, если я удаляю package UtyDate;
строка от UtyDate.pm, я не получаю ошибки. Эта ситуация существует для нескольких, но не всех моих модулей.
Существует, очевидно, намного больше кода, который я не показываю, но я смущен, как любой код, который я не показываю, мог влиять на конструкции пакета/использования, которые я показал здесь.
Когда вы используете модуль, его код запускается во время компиляции. Затем вызывается импорт имени пакета для модуля. Итак, используйте Foo;
то же самое, что BEGIN {require Foo; Foo-> импорт; }
Ваш код работал без объявлений package
, потому что весь код выполнялся в пакете main
, который используется основным кодом приложения.
Когда вы добавили объявления пакета
, он перестал работать, потому что определенные вами подпрограммы больше не определены в main
, а в UtyDate
.
Вы можете получить доступ к подпрограммам, используя полное имя UtyDate :: CurrentDate ();
, или импортируя подпрограммы в текущее пространство имен, когда вы используете
модуль.
UtyDate.pm
package UtyDate;
use strict;
use warnings;
use Exporter 'import';
# Export these symbols by default. Should be empty!
our @EXPORT = ();
# List of symbols to export. Put whatever you want available here.
our @EXPORT_OK = qw( CurrentDate AnotherSub ThisOneToo );
sub CurrentDate {
return 'blah';
}
sub AnotherSub { return 'foo'; }
Основная программа:
#!/usr/bin/perl
use strict;
use warnings;
use UtyDate 'CurrentDate';
# CurrentDate is imported and usable.
print CurrentDate(), " CurrentDate worked\n";
# AnotherSub is not
eval { AnotherSub() } or print "AnotherSub didn't work: $@\n";
# But you can still access it by its fully qualified name
print UtyDate::AnotherSub(), " UtyDate::AnotherSub works though\n";
Дополнительную информацию см. В документации Exporter .
Вам не хватает кода заголовка perl экспортера. Вам нужно добавить что-то вроде следующего в верхнюю часть вашего pm-файла под утверждением о пакете:
package UtyDate;
BEGIN {
use Exporter ();
use vars qw($VERSION @ISA @EXPORT);
$VERSION = "1.0.0";
@ISA = qw(Exporter);
@EXPORT = qw( &CurrentDate );
}
См. эту ссылку: http://perldoc.perl.org/Exporter.html#DESCRIPTION
В качестве альтернативы предложению Грея можно сделать следующее:
use UtyDate;
UtyDate::CurrentDate(...);
Кроме использования экспортера, как указывает Грей, вы можете (UGLY, но работает) также вызывать функции с именем модуля ...
Вы functiond/procedures не работают, поскольку они теперь находятся в другом пространстве имен (определенном именем модуля)
use UtyDate;
UtyDate::CurrentDate( )