2015-05-03 2 views
1

У меня есть модуль Perl .pm файла, что containts моих подпрограмм и это выглядит следующим образом:Perl `использование qw` или импортировать Подпрограммы с вечера файлы

package test; 
use strict; 
use vars qw($VERSION @ISA @EXPORT $ERROR $NAME); 
require Exporter; 
@ISA = qw(Exporter); 
@EXPORT = (
    sub1 
    sub2 
    err1 
    err2 
); 
#...etc... 

Теперь у меня есть pl файла, то, что нужно импортировать подпрограммы , но не каждый, только если они находятся в настроенном списке. Например:

@subs = ('sub1', 'sub2'); # need to load sub1 & sub2, but do not load err1 & err2 

или

@subs = ('sub1', 'err1'); # need to load sub1 & err1, but do not load sub2 & err2 

Как я могу это сделать?

Я пытался это сделать, но не работает:

my @subs = ('sub1', 'sub2'); 
use test @subs; 

Есть ли способ, чтобы загрузить только необходимые функции? И то, что необходимо, читается из SQL или файла конфигурации или любым другим способом ...

+0

Модули импортируют поддоны в другие «пространства имен», поэтому их можно вызывать по объявленному имени, а не полностью *. Поэтому вместо того, чтобы выборочно импортировать субтитры, обратитесь к ним по их полному имени. (Ваш фрагмент: 'test :: sub1()', 'test :: sub2()' и т. Д.). –

+0

Кроме того, '@ EXPORT' экспортирует все по умолчанию. Таким образом, все подсайты уже находятся в скрытом файле 'pl'. Вы можете выборочно * импортировать *, когда субсайты находятся в '@ EXPORT_OK'. –

+0

@LinusKleen: Если я использую это полное имя, загрузите в память только используемые функции? – netdjw

ответ

7

Причины код:

my @subs = ('sub1', 'sub2'); 
use test @subs; 

не работает, что use заявления оцениваются непосредственно во время синтаксического анализа, до (почти) любого другого кода. Таким образом, вторая строка вашего кода фактически запускает до, и поэтому @subs по-прежнему пуст в этой точке.

Это бы работа:

my @subs; 
BEGIN { @subs = ('sub1', 'sub2'); } 
use test @subs; 

, как бы это:

BEGIN { 
    my @subs = ('sub1', 'sub2'); 
    require test; 
    test->import(@subs); 
} 

В первом варианте, BEGIN блок используется, чтобы сделать задание @subs произойти уже во время синтаксического анализа; во второй версии весь код помещается внутри блока BEGIN, а оператор use заменяется его эквивалентом времени выполнения (require + import).


Однако у вас, вероятно, нет причин для этого. Когда вы загружаете модуль, все его кода загружается в любом случае, *, так что вы фактически не сохраняете память, просто импортируя некоторые из функций, предоставляемых модулем. Фактически, единственная реальная причина не импортировать все, что предоставляет модуль, - это избегать конфликтов между модулями, которые могут пытаться экспортировать функции с тем же именем или с вашей собственной функцией.

В любом случае, это всегда * можно вызывать функции в модуле, не импортируя их вообще, только предваряя их с именем модуля и ::. Таким образом, вместо того, чтобы:

use test qw(foo bar); 
foo(); 
bar(); 

вы можете просто сделать:

use test(); 
test::foo(); 
test::bar(); 

*) Технически, Есть несколько вещей, которые гарантировано в Perl, и это вполне возможно для чтобы реализовать какой-то механизм ленивой загрузки, который только создает функции (или загружает их из другого модуля) при их импорте. Но для этого требуется настраиваемый метод import (и/или AUTOLOAD); для обычных модулей с использованием Exporter приведенное выше упрощенное описание является истинным.

+0

Спасибо, что ответили. И следующий вопрос: как я могу сэкономить память и время компиляции с помощью модулей perl и 'use'? Можно вообще? – netdjw

+0

Это может быть предметом отдельного вопроса, но только для начала см. [AutoLoader] (http://perldoc.perl.org/AutoLoader.html) и [SelfLoader] (http://perldoc.perl.org). /SelfLoader.html) и раздел [«Автозагрузка» в perlsub] (http://perldoc.perl.org/perlsub.html#Autoloading). –

-1

Прежде всего, все глобальные глоссарии Perl должны использовать заглавные буквы, поэтому имя вашего пакета должно начинаться с заглавной буквы, а имя файл должен быть изменен, чтобы договориться

Во-вторых, существует гораздо меньше накладных расходов, если вместо наследуя от Exporter, вы загрузите его import метод непосредственно

Я не понимаю, что такие вещи err1 и err2 есть, но следует поставить по желанию экспорт в массиве @EXPORT_OK

Это оставляет свой модуль, глядя, как этот

Test.pm

package Test; 

use strict; 
use warnings; 

use Exporter 'import'; 

our @EXPORT_OK = qw/ sub1 sub2 /; 

sub sub1 { 
    print "sub1\n"; 
} 

sub sub2 { 
    print "sub2\n"; 
} 

и программа, которая использует это будет выглядеть следующим образом

use strict; 
use warnings; 

use Test qw/ sub1 /; 

sub1; 

sub1 
+3

Это хороший совет, но я не думаю, что он на самом деле отвечает на вопрос OP. См. Мой ответ на то, что я считаю фактической проблемой, с которой сталкивается ОП. –

 Смежные вопросы

  • Нет связанных вопросов^_^