Вы:
- Написание модуля и хотите узнать, как экспортировать подпрограмму?
- Вы смотрите на модуль и хотите использовать подпрограмму из него?
Для ответа на первый вопрос ответ обычно составляет Не экспортируйте ничего автоматически . Если вы поместите список имен подпрограмм в список @EXPORT_OK
, вы можете экспортировать эти подпрограммы, используя следующий синтаксис в основной программе:
use My::Module qw(subroutines to be imported);
Если вы хотите автоматически импортировать подпрограмму, вы можете поместить ее в список @EXPORT
. Они будут автоматически импортированы так, как File::Copy
автоматически импортирует подпрограмму копирования.
Теперь современные стандарты Perl не одобряются при экспорте чего-либо, потому что это загрязняет пространство имен пользователя без необходимости информировать пользователя. Если вы действительно, действительно хотите импортировать что-то, теперь стандарт должен использовать @EXPORT_OK
, поэтому пользователь должен перечислить подпрограммы, которые он хочет импортировать, в своем операторе use
. Это как минимум документирует загрязнение.
Некоторые современные модули, такие как File::Spec
, ничего не импортируют. Вы должны либо поставить префикс подпрограммы перед именем модуля, либо использовать объектно-ориентированный синтаксис (даже если, как и File::Spec
, он на самом деле не объектно-ориентирован, так как нет объектов для ориентации.)
Что подводит нас к другому: используйте объектно-ориентированный Perl в своих модулях. Тогда вам не нужно беспокоиться об экспорте чего-либо, потому что вы не работаете в OOPerl.
Если вы пытаетесь ответить на второй вопрос и просто пытаетесь найти имена подпрограмм из стороннего модуля, используйте команду perldoc
и посмотрите документацию. Вы можете посмотреть @EXPORT
и список @EXPORT_OK
, чтобы увидеть, что экспортируется, но могут быть вещи, которые не экспортируются (например, переменная $File::Find::Name
в модуле File::Find
), которые могут быть важны.
Если вы действительно хотите потерпеть неудачу, попробуйте просмотреть каждую переменную пакета следующим образом:
#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
while (my ($var, $type) = each %Foo::) {
if (defined &$type) {
say "$var is a subroutine";
}
else {
say "$var is defined as something or another";
}
}
package Foo;
our %bar = (foo => 1, bar => 2);
our @foo = qw(foo bar);
our $fubar = "barfu";
sub barfu {
print "FOO!";
return "FOO!";
}
Это пройдёт через пакет, покажет вам, что определено, и даже скажет вам, подпрограмма это или нет. Я получаю следующий вывод:
barfu is a subroutine
fubar is defined as something or another
bar is defined as something or another
foo is defined as something or another
Я не смог выяснить, как увидеть, к какому типу переменных это относится, кроме как к определенной подпрограмме. Может быть, кто-то еще может помочь мне понять это. Возможно, мне придется что-то делать с eval
.
Модификация с Эриком Штормом
Следующий тип покажет, что это. К сожалению, это скажет, что все скаляр и шар. Глоб это понятно (это шар) но скаляр? Полагаю, пока просто оставьте эти типы вне цикла for.
#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
use Data::Dumper;
while (my ($var, $type) = each %Foo::) {
print "$var";
# foreach my $ref_type (qw(SCALAR GLOB ARRAY HASH CODE REF LVALUE FORMAT IO VSTRING Regexp)) {
foreach my $ref_type (qw(ARRAY HASH CODE REF LVALUE FORMAT IO VSTRING Regexp)) {
if (defined *$type{$ref_type}) {
say qq("$var" is a type $ref_type);
}
}
}
package Foo;
our %bar = (foo => 1, bar => 2);
our @foo = qw(foo bar);
our $fubar = "barfu";
sub barfu {
print "FOO!";
return "FOO!";
}