![]() |
|
Модераторы: korob2001, ginnie |
![]()
|
|
| Logo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
Как проверить, существует ли определенный пакет в программе? Как удалить пакет и все его переменные?
|
|||
|
||||
| sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
проверить загруженному пакету соответсвует соответвует таблица символов.
таблица символов - это обычный хэш с именем совпадающим с пакетом. Например если пакет называется Data::Dumper, то его таблица символов %Data::Dumper:: (двоеточия в конце обязательны). Сама таблица символов пакета (т.е. хэш) является записью в таблице символов основного пакета (main). Поэтому проверить наличие пакета можно так:
А зачем вам понадобилось удалять пакет ? Память вам освободить не удастся. Можно конечо удалить те переменные которые вы импортировали в свой пакет. Это сообщение отредактировал(а) sir_nuf_nuf - 21.2.2010, 17:33 |
|||
|
||||
| Nab |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 582 Регистрация: 25.3.2006 Где: Kiev Репутация: 26 Всего: 37 |
if (exists $INC{$module_name}) $packet_name->unimport;
где $module_name = 'CGI/Carp.pm' а $packet_name = 'CGI::Carp' вообщето более правильно сказать: no CGI::Carp; Но тут с тонкостями нужно разбираться... я уже подзабыл немного :( -------------------- Чтобы правильно задать вопрос нужно знать больше половины ответа... Perl Community FREESCO in Ukraine |
|||
|
||||
| arto |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1495 Регистрация: 31.10.2004 Репутация: 38 Всего: 40 |
# perl -MCGI::Carp -le 'no CGI::Carp; croak "hi!"'
[Thu Feb 25 16:09:04 2010] -e: hi! at -e line 1 # |
|||
|
||||
| Nab |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 582 Регистрация: 25.3.2006 Где: Kiev Репутация: 26 Всего: 37 |
arto, ты как всегда, прийдешь и одной строкой всю малину испортишь
IMHO use и no это больше компиляция, а на этапе выполнения import и unimport. Поправьте меня, потому как я долго был с перлом в разлуке ;) -------------------- Чтобы правильно задать вопрос нужно знать больше половины ответа... Perl Community FREESCO in Ukraine |
|||
|
||||
| Logo |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
Вообще
BEGIN выполняется на стадии компиляции. Но сабж не о модулях, а о пакетах. sir_nuf_nuf правильно сказал как проверить пакет, а вот как его удалить? Подобные фокусы с пакетами делает модуль Class::Prototyped, правда как он это делает пока не разобрался.
Почему не удастся? Надо потому что создается пакет динамически, и убрать его за собой тоже надо бы. См. модуль Class::Prototyped, он удаляет пакеты объектов, которые перестали существовать. |
||||
|
|||||
| Logo |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
Разобрался как..
Кстате, Class::Prototyped делает это не полностью, не освобождая переменные и функции(в т.ч. те функции которые сам создал), а только таблицу имен. upd: Беру свои слова обратно. Походу функции он освобождает функции и переменные, где-то в другом месте кода, причем с учетом счетчика ссылок на них. Это сообщение отредактировал(а) Logo - 26.2.2010, 11:55 |
|||
|
||||
| sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
Итак, поправьте меня если я не прав.
Что такое пакет ? - это набор perl структур (скаляры, массивы, функции и т.п.), сложенные в хеш - таблицу имен. Они висят в памяти потому что на них есть ссылки из этого самого хеша (точне есть ссылки на globы, а glob ссылаются на все остальное) Что бы удалить их из памяти - нужно что бы этих ссылок не осталось. Для этого нужно: а) удалить саму таблицу имен. %Data::Dumper:: = (); б) удалить все другие ссылки. Таких может быть туева хуча:
в) логично было бы еще INC почистить, если пакет загружался из модуль. Но есть и нюансы: а) память освободится только для perl б) XS вы так не выгрузите Так что в общем случае - это довольно бессмысленная процедура. Лучше - сформулируйте зачем вам нужно очищать пространства имен ? Пространстов имен по идее жестко связано с определенным функционалом. Если вы хотите положить в то же пространство другие функции - это плохо. (В таком случае лучше использовать ООП) реквестирую XS гуру в тред. |
|||
|
||||
| vadiml |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 310 Регистрация: 27.7.2007 Репутация: 5 Всего: 7 |
> Что такое пакет ? - это набор perl структур (скаляры, массивы, функции и т.п.), сложенные в хеш - таблицу имен.
Боюсь Вы немного путаете пакет и объект. Модуль -- это фактически файл Пакет -- это пространство имён, которое при желании можно экспортировать в другое пространство имён Объект -- это как раз то, что хранится в памяти, хотя и не обязательно что это хеш, если это XS-объект (хотя так и не совсем корректно говорить), то это скаляр, Magic от реального адреса. Объект удалится из памяти как только на него не останется на него perl-ссылок (если XS -- то и это не факт, там могут быть свои ссылки). Откомпилировался он сразу, используя use, или не (require, eval) -- тут не имеет значения, подгружается в память всё, предкомпиляция повлияет только на скорость исполнения. |
|||
|
||||
| sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
да, я в курсе. просто в этом треде мы обсуждаем как устроены пространства имен. устроены они именно в виде хешей содержащих глобы, которые ссылаются на процедуры и переменные данного пакета экспортирование - по сути копирование одного глобов (или частей) из хеша в хеш И вопрос был в том как удадить пакет из загруженой программы. Это сообщение отредактировал(а) sir_nuf_nuf - 26.2.2010, 13:05 |
|||
|
||||
| Logo |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
Можно явно сделать undef всем скалярам, массивам и т.п, и тогда все ссылки идут лесом. Почему-то недостаточно удалить элемет таблицы имен, надо еще сделать undef typeglob-у. Таким образом, методом научного тыка подобран такой алгоритм удаления пакета. - Обходим таблицу имен пакета и делаем: delete ${"$package\::"}{$key}; undef(*{"$package\::$key"}); - Если надо удалить и то, на что есть ссылки извне, делаем: undef(&{"$package\::$key"}); undef(${"$package\::$key"}); и т.д. Причем до удаления typeglob. Делаем
Так все же так. Лишь некоторые системы могут использовать освободившуюся память (Из кемелбука про Perl 5.6).
Вот этого не знаю... Еще... написал текст выше и проверил - оказывается если бездумно грохнуть все Perl структуры в пакете, это коснется и того, что в этот пакет экспортировано, чего конечно допустить нельзя. Мне тогда будет достаточно удалить только то, на что нет ссылок извне. Это сообщение отредактировал(а) Logo - 26.2.2010, 14:24 |
||||||||
|
|||||||||
| Logo |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 694 Регистрация: 22.7.2008 Репутация: 3 Всего: 10 |
Class::Prototyped например вынужден такие вещи делать. А у меня модуль для добавления условий в виде Perl кода, для написания разных утилит. К примеру что бы сделать такую утилиту для поиска картинок.
У условий - свое пространство имен, в которое можно экспортировать функции из других модулей. Создается оно при создании объекта с набором условий, и удалятся должно при DESTROY этого объекта. Это сообщение отредактировал(а) Logo - 26.2.2010, 13:58 |
||||
|
|||||
| DurRandir |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 14 Всего: 17 |
Если это утилита для командной строки - я бы не заморачивался и ничего не делал. Всё равно работает недолго.
|
|||
|
||||
![]()
|
| Правила форума "Perl" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |