Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Множественная загрузка модуля, Множественная загрузка модуля 
V
    Опции темы
DProf
Дата 3.10.2014, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 28.9.2012

Репутация: 1
Всего: 1



Добрый день!

Вопрос скорее теоретический.
Возникла необходимость несколько раз подряд загружать один и тот же модуль. Смысл в том, что в зависимости от переменных окружения (которые изменяются в процессе работы программы) он возвращает разные значения переменных. То есть надо уже загруженный модуль загрузить снова и он вернет другие значения. Какие тут есть пути?

Я так понял, что либо eval "module_code" , либо do "module_path", иного способа делать это нет.

Модуль сторонний, лезть в него не очень... Лучшее решение тут, конечно, функция в самом модуле, которая вернет то что надо в зависимости от переменных окружения. Тогда один раз его загрузить и пользоваться функцией. Но раз разработчик модуля это не предусмотрел, то либо расширять модуль такой функцией, либо несколько раз подряд загружать один и тот же модуль.

Это сообщение отредактировал(а) DProf - 3.10.2014, 13:36
PM MAIL   Вверх
tzirechnoy
Дата 3.10.2014, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

Репутация: нет
Всего: 16



Цитата
Какие тут есть пути?


Как минимум -- прекратить называть эту хрень модулем.

А так -- в perldoc -f use и perldoc -f require -- вполне внятным перловым языком описано, что эти команды делают, соответственно, из них понятно -- как это сделать много раз и со своими прибабахами.
PM MAIL   Вверх
DProf
Дата 3.10.2014, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 28.9.2012

Репутация: 1
Всего: 1



Цитата

прекратить называть эту хрень модулем

Согласен, переписал его по-человечески. С функцией, о которой писал. Теперь его можно модулем назвать smile и задача решена.

А изучение perldoc -f use и perldoc -f require привело меня лишь к тому, что не обойтись без выяснения пути к файлу и далее eval его кода (как в sub require из perldoc -f require). А то я надеялся на параметр какой то у require, который отменит 
Цитата
 Note that the file will not be included twice under the same specified name. 

PM MAIL   Вверх
Pfailed
Дата 3.10.2014, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 19.7.2009

Репутация: 22
Всего: 39



Цитата(DProf @  3.10.2014,  17:59 Найти цитируемый пост)
А то я надеялся на параметр какой то у require, который отменит 

От этого может помочь удаление записи из глобального хеша %INC. Насколько знаю require там и проверяет не загружен ли модуль. Соотвтетственно после "require My::Module" появится запись $INC{"My/Module.pm"}, которую можно delete.
Ещё может оказаться полезным Symbol::delete_package и Class::Unload



--------------------
PM MAIL   Вверх
Ihost
Дата 7.11.2014, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 14.9.2012

Репутация: нет
Всего: нет



Есть две большие разницы между группой конструкций вида require/do и use/no, первые из которых занимаются импортом и первичным исполнением предложенного программного модуля, а вторые отвечают за загрузку и выгрузку структурированного Perl-модуля, в том числе с участием спецификации Exporter
В хорошей реализации ничто не мешает сделать вам локальные вызовы use и no в надлежащем порядке
PM MAIL   Вверх
arto
Дата 7.11.2014, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 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
#
PM MAIL ICQ   Вверх
Ihost
Дата 10.11.2014, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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"; }
PM MAIL   Вверх
Ihost
Дата 10.11.2014, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 14.9.2012

Репутация: нет
Всего: нет



И да полный ответ с технической точки зрения, чтобы не осталось вопросов по реализации, для простоты два файла в одной директории
Файл MyProgram.pl
Код

#!/usr/bin/perl
eval("use MyModule;");
print "Hello world 1 \n";
eval("no MyModule;");
print "Hello world 2 \n";
eval("use MyModule; ");
print "Hello world 3 \n";
exit;

Файл MyModule.pm
Код

#!/usr/bin/perl
package MyModule;
print "Hello from module \n";
sub import {print "Import from module \n";
}
sub unimport {print "Unimport from module \n";
}
1;

Да очевидно все вызовы use/no в текущем контексте всплывают в начало потока исполнения, поэтому чтобы оставить их на своем месте, добавлена функция eval; можно использовать и другие условные конструкции


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



PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0823 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.