![]() |
Модераторы: korob2001, ginnie |
![]() ![]() ![]() |
|
DProf |
|
|||
Новичок Профиль Группа: Участник Сообщений: 39 Регистрация: 28.9.2012 Репутация: 1 Всего: 1 |
Добрый день!
Вопрос скорее теоретический. Возникла необходимость несколько раз подряд загружать один и тот же модуль. Смысл в том, что в зависимости от переменных окружения (которые изменяются в процессе работы программы) он возвращает разные значения переменных. То есть надо уже загруженный модуль загрузить снова и он вернет другие значения. Какие тут есть пути? Я так понял, что либо eval "module_code" , либо do "module_path", иного способа делать это нет. Модуль сторонний, лезть в него не очень... Лучшее решение тут, конечно, функция в самом модуле, которая вернет то что надо в зависимости от переменных окружения. Тогда один раз его загрузить и пользоваться функцией. Но раз разработчик модуля это не предусмотрел, то либо расширять модуль такой функцией, либо несколько раз подряд загружать один и тот же модуль. Это сообщение отредактировал(а) DProf - 3.10.2014, 13:36 |
|||
|
||||
tzirechnoy |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1173 Регистрация: 30.1.2009 Репутация: нет Всего: 16 |
Как минимум -- прекратить называть эту хрень модулем. А так -- в perldoc -f use и perldoc -f require -- вполне внятным перловым языком описано, что эти команды делают, соответственно, из них понятно -- как это сделать много раз и со своими прибабахами. |
|||
|
||||
DProf |
|
||||
Новичок Профиль Группа: Участник Сообщений: 39 Регистрация: 28.9.2012 Репутация: 1 Всего: 1 |
Согласен, переписал его по-человечески. С функцией, о которой писал. Теперь его можно модулем назвать ![]() А изучение perldoc -f use и perldoc -f require привело меня лишь к тому, что не обойтись без выяснения пути к файлу и далее eval его кода (как в sub require из perldoc -f require). А то я надеялся на параметр какой то у require, который отменит
|
||||
|
|||||
Pfailed |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 933 Регистрация: 19.7.2009 Репутация: 22 Всего: 39 |
От этого может помочь удаление записи из глобального хеша %INC. Насколько знаю require там и проверяет не загружен ли модуль. Соотвтетственно после "require My::Module" появится запись $INC{"My/Module.pm"}, которую можно delete. Ещё может оказаться полезным Symbol::delete_package и Class::Unload |
|||
|
||||
Ihost |
|
|||
Новичок Профиль Группа: Участник Сообщений: 24 Регистрация: 14.9.2012 Репутация: нет Всего: нет |
Есть две большие разницы между группой конструкций вида require/do и use/no, первые из которых занимаются импортом и первичным исполнением предложенного программного модуля, а вторые отвечают за загрузку и выгрузку структурированного Perl-модуля, в том числе с участием спецификации Exporter
В хорошей реализации ничто не мешает сделать вам локальные вызовы use и no в надлежащем порядке |
|||
|
||||
arto |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1495 Регистрация: 31.10.2004 Репутация: 38 Всего: 40 |
# 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 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 24 Регистрация: 14.9.2012 Репутация: нет Всего: нет |
Да совершенно ожидаемый результат, *включение* модуля действительно выполняется один раз при помощи неявного require, обратить выполнение его невозможно
Действительно же Perl преобразует конструкции типа use Module во включения вида BEGIN { require "Module.pm"; }, именно по этой причине добавления неявного require в BEGIN-обертку, путь для поиска целевых модулей необходимо прописывать тоже в BEGIN-блоке, иначе программа сразу же завершится с ошибкой Тут дело в другом- штукенция под названием T.pm не совсем модуль, хотя формально и является *умным пакетом*, и возвращает единицу НО самое главное в модуле- это механизм экспорта элементов, который и основывается на use/no и модуле Exporter Здесь же этого нет, следовательно модуль никак фактически не реагирует на use/no, с таким же успехом можно было написать BEGIN {require "T.pm"; } |
|||
|
||||
Ihost |
|
||||
Новичок Профиль Группа: Участник Сообщений: 24 Регистрация: 14.9.2012 Репутация: нет Всего: нет |
И да полный ответ с технической точки зрения, чтобы не осталось вопросов по реализации, для простоты два файла в одной директории
Файл MyProgram.pl
Файл MyModule.pm
Да очевидно все вызовы use/no в текущем контексте всплывают в начало потока исполнения, поэтому чтобы оставить их на своем месте, добавлена функция eval; можно использовать и другие условные конструкции С архитектурной точки зрения важно просто помнить и понимать, что является модулем в Perl-философии, а что нет По аналогии как если в вашей программе есть классы, не значит, что это объектно-ориентированное программирование |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "Perl" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |