Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Perl: Общие вопросы > Множественная загрузка модуля |
Автор: DProf 3.10.2014, 13:31 |
Добрый день! Вопрос скорее теоретический. Возникла необходимость несколько раз подряд загружать один и тот же модуль. Смысл в том, что в зависимости от переменных окружения (которые изменяются в процессе работы программы) он возвращает разные значения переменных. То есть надо уже загруженный модуль загрузить снова и он вернет другие значения. Какие тут есть пути? Я так понял, что либо eval "module_code" , либо do "module_path", иного способа делать это нет. Модуль сторонний, лезть в него не очень... Лучшее решение тут, конечно, функция в самом модуле, которая вернет то что надо в зависимости от переменных окружения. Тогда один раз его загрузить и пользоваться функцией. Но раз разработчик модуля это не предусмотрел, то либо расширять модуль такой функцией, либо несколько раз подряд загружать один и тот же модуль. |
Автор: tzirechnoy 3.10.2014, 15:59 | ||
Как минимум -- прекратить называть эту хрень модулем. А так -- в perldoc -f use и perldoc -f require -- вполне внятным перловым языком описано, что эти команды делают, соответственно, из них понятно -- как это сделать много раз и со своими прибабахами. |
Автор: DProf 3.10.2014, 17:59 | ||||
Согласен, переписал его по-человечески. С функцией, о которой писал. Теперь его можно модулем назвать ![]() А изучение perldoc -f use и perldoc -f require привело меня лишь к тому, что не обойтись без выяснения пути к файлу и далее eval его кода (как в sub require из perldoc -f require). А то я надеялся на параметр какой то у require, который отменит
|
Автор: Pfailed 3.10.2014, 21:49 |
От этого может помочь удаление записи из глобального хеша %INC. Насколько знаю require там и проверяет не загружен ли модуль. Соотвтетственно после "require My::Module" появится запись $INC{"My/Module.pm"}, которую можно delete. Ещё может оказаться полезным Symbol::delete_package и Class::Unload |
Автор: Ihost 7.11.2014, 13:00 |
Есть две большие разницы между группой конструкций вида require/do и use/no, первые из которых занимаются импортом и первичным исполнением предложенного программного модуля, а вторые отвечают за загрузку и выгрузку структурированного Perl-модуля, в том числе с участием спецификации Exporter В хорошей реализации ничто не мешает сделать вам локальные вызовы use и no в надлежащем порядке |
Автор: arto 7.11.2014, 16:59 |
# cat > T.pm package T; our $internalvar = $ENV{'T'}; 1; ^D # T=10 perl -l use T; print "use T: $T::internalvar"; $ENV{'T'} = 20; no T; print "no T: $T::internalvar"; use T; print "use T: $T::internalvar"; ^D use T: 10 no T: 10 use T: 10 # |
Автор: Ihost 10.11.2014, 12:44 |
Да совершенно ожидаемый результат, *включение* модуля действительно выполняется один раз при помощи неявного require, обратить выполнение его невозможно Действительно же Perl преобразует конструкции типа use Module во включения вида BEGIN { require "Module.pm"; }, именно по этой причине добавления неявного require в BEGIN-обертку, путь для поиска целевых модулей необходимо прописывать тоже в BEGIN-блоке, иначе программа сразу же завершится с ошибкой Тут дело в другом- штукенция под названием T.pm не совсем модуль, хотя формально и является *умным пакетом*, и возвращает единицу НО самое главное в модуле- это механизм экспорта элементов, который и основывается на use/no и модуле Exporter Здесь же этого нет, следовательно модуль никак фактически не реагирует на use/no, с таким же успехом можно было написать BEGIN {require "T.pm"; } |
Автор: Ihost 10.11.2014, 13:43 | ||||
И да полный ответ с технической точки зрения, чтобы не осталось вопросов по реализации, для простоты два файла в одной директории Файл MyProgram.pl
Файл MyModule.pm
Да очевидно все вызовы use/no в текущем контексте всплывают в начало потока исполнения, поэтому чтобы оставить их на своем месте, добавлена функция eval; можно использовать и другие условные конструкции С архитектурной точки зрения важно просто помнить и понимать, что является модулем в Perl-философии, а что нет По аналогии как если в вашей программе есть классы, не значит, что это объектно-ориентированное программирование |