![]() |
Модераторы: korob2001, ginnie |
![]() ![]() ![]() |
|
ADm |
|
||||
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 19.6.2006 Где: Россия Репутация: нет Всего: нет |
Привет All!
Столкнулся с такой проблемой - сохраняю в сессию (использую CGI::Session) объект (скажем класса MyApp::User) - все ок, все поля объекта в сессию ложаться. забираю объект из сессии - тоже все замечательно, Data::Dumper показывает следующее (для забранного объекта):
те получил я именно объект и нужного мне класса, но (!) при попытке вызвать метод класса (любой, скажем getName - метод кстати объявлен) перл выдает ошибку:
Знает ли кто, что сие значит? это глюк CGI::Session или руки кривые или еще что? |
||||
|
|||||
DEER |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 749 Регистрация: 12.4.2005 Где: г. Рязань Репутация: 2 Всего: 13 |
сорри, может гоню, но сделано ли
? -------------------- |
|||
|
||||
krypt3r |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 359 Регистрация: 9.6.2009 Репутация: нет Всего: 16 |
Не может найти метод getName класса MyApp::User.
ЗЫ. Включите в скрипте стрикт и варнинги. |
|||
|
||||
ADm |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 19.6.2006 Где: Россия Репутация: нет Всего: нет |
это ясно что не может найти, но вот почему? PS: use warnings; use strict; делаю всегда Добавлено через 2 минуты и 39 секунд
спасибо за совет - сделал, заработало. но вот интересно почему не работает? может знает кто из присутствующих куда копать и что почитать? интересно%) |
||||||
|
|||||||
DurRandir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 1 Всего: 17 |
Потому что у вас в момент сохранения объекта этот модуль был загружен, а в момент загрузки - нет. Методы у объекта - это обычные функции, хранящиеся в модуле MyApp::User. Нет модуля - нет функций - невозможно вызвать метод.
|
|||
|
||||
ADm |
|
|||
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 19.6.2006 Где: Россия Репутация: нет Всего: нет |
Вы правы. но думаю тут дело немного в другом (хотя причина в незагрузке модуля) - сериализатор неправильно восстанавливает класс, он просто загружает сохраненную структуру и благословит ее, хотя по логике должен бы вернуть полноценный объект, неявно загрузив класс (ведь это от него и ожидается). |
|||
|
||||
DurRandir |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 1 Всего: 17 |
В общем случае - он совершенно не обязан это делать. Storable точно не делает. То, что модуль MyApp::User лежит по пути из @INC (a @INC в момент сохранения и загрузки совпадают? сериализатор об этом не знает) в файле MyApp/User.pm - это только удобное соглашение. В рантайме можно создавать новые классы, без использования use - и у них не будет никакого соответствующего файла, который можно use'нуть.
Можете отнаследовать от сериализатора и грузить отсутствующие классы - но тогда учитывайте вышеописанные проблемы. |
|||
|
||||
ADm |
|
|||
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 19.6.2006 Где: Россия Репутация: нет Всего: нет |
мне кажется обязан - если вы положили в сессию объект, то его вы и хотите получить назад. почему я должен думать как там сериализатор его хранит и восстанавливает? @INC в момент сохранения и восстановления совпадают PS: добавил сточку eval "require ".ref($user); после получения объекта из сессии... |
|||
|
||||
DurRandir |
|
||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 1 Всего: 17 |
А сериализатор откуда это знает? Это не волшебная машинка ![]()
Где сериализатору брать описание Unexistant::Class? ![]() ЗЫ: строковый eval это плохо. Если заранее известно, объекты каких классов могут быть получены - лучше их загрузить через use в самом начале. Если не известно - то хотя бы не вызывать eval, если такой класс уже заружен. Это сообщение отредактировал(а) DurRandir - 28.10.2009, 11:43 |
||||||
|
|||||||
shamber |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1422 Регистрация: 5.9.2006 Где: Россия Репутация: нет Всего: 18 |
||||
|
||||
ADm |
|
|||
Новичок Профиль Группа: Участник Сообщений: 31 Регистрация: 19.6.2006 Где: Россия Репутация: нет Всего: нет |
а зачем ему это знать? если модули в момент воостановления куда-то пропали или изменился INC - это проблема программиста ну а зачем так делать? правильней объявить класс а в нем метод remove который принимает в качестве параметра имя ключа хэша который надо удалить. кстати, что такое "subname"? интересно, а можно поподробней почему? и кстати внутри eval - require он то и проверяет загружен уже модуль или нет, разве нет? |
|||
|
||||
DurRandir |
|
||||||||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 335 Регистрация: 27.9.2009 Репутация: 1 Всего: 17 |
Это из Sub::Name. Для профайлера/бэктрейсов - чтобы показывали не __ANON__, а "remove_smth" Зачем таким образом? Мне удобнее вызывать не $obj->get('apples', 5), a $obj->get_apples(5). Я могу использовать много разных ключей, и, при опечатке, я получу не пустое значение (или +код на проверку ключа), а автоматом - Undefined subroutine. Я могу создавать объекты с разными наборами ключей. Так что - удобство ![]()
Ну так не мне надо, чтобы он загрузил "всё как было". Ему дали данные, он их и восстановил. Загрузить класс - это восстановить метаданные.
Два аспекта. Первое - безопасность perl -e 'use Data::Dumper; $z=bless {}, "Good::Class; malicious_code"; print ref($z)' ..и в eval это) Входные данные не должны исполняться напрямую. По хорошему - вообще не должны исполняться, но это как получится. Второе - строковый eval каждый раз вызывает разбор кода, который лежит в строчке - вызов парсера вещь очень недешевая. Да, require проверит, был ли файл загружен - но перед этим вызовом всё равно будет вызван парсер для eval'a.
Mагический хеш %INC ![]() Это сообщение отредактировал(а) DurRandir - 28.10.2009, 15:02 |
||||||||
|
|||||||||
![]() ![]() ![]() |
Правила форума "Perl: CGI программирование" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Perl: разработка для Web | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |