2016-07-05 2 views
9

У меня есть модуль под названием hsfSubs.pm в моей папке perl\lib. У меня ничего нет в модуле, но подпрограммы и 1; в конце.В Perl, зачем мне нужен экспортер?

Одна подпрограмма, например, называется pause. Я не выполнял никаких процедур импорта или экспорта.

В моих основных программах я просто говорю use hsfSubs;, и в дальнейшем я могу позвонить pause без проблем. То же самое, если я скажу use hsfSubs qw(pause);.

Зачем использовать экспортер @EXPORT и @EXPORT_OK и т. Д. Или любые другие осложнения?

Несколько ответов на переполнение стека на вопросы об экспортере рассказывают, как его использовать, но я не понимаю, зачем его использовать.

ответ

13

Короткий вариант заключается в том, что вы хотели получить модуль, но в итоге вы получили то, что this вызывает библиотеку. Это не хорошо, потому что они загрязняют пространство имен вызывающего абонента (что может вызвать множество проблем). Но более важно здесь, загружая их, используя require или use (в качестве противопоставления do) является ошибкой.

Если бы это было правильно написано как модуль, ваш пример не сработает. Экспортер - это решение этой проблемы.


Давайте погрузиться в детали.

Как я уже сказал, есть проблемы с вашим модулем. Как вы заметили, он иногда работает, несмотря на ошибку.

$ cat Buggy.pm 
sub test { "ok!" } 
1; 

$ perl -e'use Buggy; CORE::say(test());' 
ok! 

Но это только потому, что ваш пример слишком прост. Давайте добавим правильно правильно написанный модуль [1].

$ cat Buggy.pm 
sub test { "ok!" } 
1; 

$ cat Other.pm 
package Other; 
use Buggy; 
1; 

$ perl -e'use Other; use Buggy; CORE::say(test());' 
Undefined subroutine &main::test called at -e line 1. 

Исправлена ​​ошибка в модуле является то, что он не имеет package директиву. Модули, загруженные с использованием use и require, должны всегда использовать директиву package. Но как только вы это добавите, ваш модуль перестает работать.

$ cat NotBuggy.pm 
package NotBuggy; 
sub test { "ok!" } 
1; 

$ perl -e'use NotBuggy; CORE::say(test());' 
Undefined subroutine &main::test called at -e line 1. 

Экспортер используется для решения этой проблемы.

$ cat Final.pm 
package Final; 
use Exporter qw(import); 
our @EXPORT = qw(test); 
sub test { "ok!" } 
1; 

$ perl -e'use Final; CORE::say(test());' 
ok! 

  1. Ну, не совсем. Если бы это было правильно написано, оно включало бы использование use strict; use warnings 'all';. Всегда включайте это! Здесь это было опущено, чтобы держать вещи визуально простыми.
+0

Спасибо. Я вижу разницу. Но «библиотека» - это то, что я хотел. Единственная причина, по которой я могу получить модуль, - это отсутствие другого способа получить библиотеку. Причудливо сказать, что если бы я написал это правильно, это не сработало бы. ЛОЛ. Я полагаю, что «загрязнение» находится в сознании наблюдателя. Я не рассматриваю возможность доступа к моим собственным подпрограммам как загрязнение. Ненужная сложность - это загрязнение. – user1067305

+1

Загрязнение - это не наличие желаемых вещей; это присутствие нежелательных вещей.Проблема в том, что у вас есть доступ не только к субмашинам, которые вы хотите экспортировать, но и к внутренним модулям вашего модуля. Это эквивалент глобальных переменных. Программирование - это все, что связано с ограничением возможностей, и полная противоположность тому, что вы сказали, хорошо. Создание всего глобального затрудняет чтение, отладки, поддержку и т. Д. Нет, это не проблема стиля. Все программисты на Perl перестали использовать эти «библиотеки», когда Perl добавила поддержку поддержки пространства имен 20 лет назад. – ikegami

+6

Короче говоря, разделение кода требует небольшого дополнительного кода, но это делает программу намного менее сложной. – ikegami

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