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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Q]: проблемы с хранением объектов в сессии, проблемы с хранением объектов в сессии 
:(
    Опции темы
ADm
  Дата 27.10.2009, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Привет All!

Столкнулся с такой проблемой - сохраняю в сессию (использую CGI::Session) объект (скажем класса MyApp::User) - все ок, все поля объекта в сессию ложаться.
забираю объект из сессии - тоже все замечательно, Data::Dumper показывает следующее (для забранного объекта):
Код

bless( {
                 '_name' => 'User1',
                 '_register_date' => '1256563439',
                 '_id' => '1',
                 '_login' => 'user1',
                 '_password' => undef,
                 '_last_login_date' => '1256643784',
                 '_email' => ''
}, 'MyApp::User' );


те получил я именно объект и нужного мне класса, но (!) при попытке вызвать метод класса (любой, скажем getName - метод кстати объявлен) перл выдает ошибку:
Код

   Can't locate object method "getName" via package "MyApp::User"


Знает ли кто, что сие значит? это глюк CGI::Session или руки кривые или еще что?


PM MAIL ICQ Jabber   Вверх
DEER
Дата 27.10.2009, 17:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 749
Регистрация: 12.4.2005
Где: г. Рязань

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



сорри, может гоню, но сделано ли
Код

use MyApp::User;

?


--------------------
 
PM MAIL WWW ICQ MSN   Вверх
krypt3r
Дата 27.10.2009, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Не может найти метод getName класса MyApp::User.

ЗЫ. Включите в скрипте стрикт и варнинги.
PM MAIL   Вверх
ADm
Дата 27.10.2009, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(krypt3r @ 27.10.2009,  17:50)
Не может найти метод getName класса MyApp::User.

ЗЫ. Включите в скрипте стрикт и варнинги.

это ясно что не может найти, но вот почему?

PS: use warnings; use strict; делаю всегда

Добавлено через 2 минуты и 39 секунд
Цитата(DEER @ 27.10.2009,  17:34)
сорри, может гоню, но сделано ли
Код

use MyApp::User;

?

спасибо за совет - сделал, заработало.
но вот интересно почему не работает? может знает кто из присутствующих куда копать и что почитать? интересно%)
PM MAIL ICQ Jabber   Вверх
DurRandir
Дата 28.10.2009, 06:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Потому что у вас в момент сохранения объекта этот модуль был загружен, а в момент загрузки - нет. Методы у объекта - это обычные функции, хранящиеся в модуле MyApp::User. Нет модуля - нет функций - невозможно вызвать метод.
PM   Вверх
ADm
Дата 28.10.2009, 09:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(DurRandir @ 28.10.2009,  06:15)
Потому что у вас в момент сохранения объекта этот модуль был загружен, а в момент загрузки - нет. Методы у объекта - это обычные функции, хранящиеся в модуле MyApp::User. Нет модуля - нет функций - невозможно вызвать метод.

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

PM MAIL ICQ Jabber   Вверх
DurRandir
Дата 28.10.2009, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



В общем случае - он совершенно не обязан это делать. Storable точно не делает. То, что модуль MyApp::User лежит по пути из @INC (a @INC в момент сохранения и загрузки совпадают? сериализатор об этом не знает) в файле MyApp/User.pm - это только удобное соглашение. В рантайме можно создавать новые классы, без использования use - и у них не будет никакого соответствующего файла, который можно use'нуть.

Можете отнаследовать от сериализатора и грузить отсутствующие классы - но тогда учитывайте вышеописанные проблемы.
PM   Вверх
ADm
Дата 28.10.2009, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(DurRandir @ 28.10.2009,  09:38)
В общем случае - он совершенно не обязан это делать. Storable точно не делает. То, что модуль MyApp::User лежит по пути из @INC (a @INC в момент сохранения и загрузки совпадают? сериализатор об этом не знает) в файле MyApp/User.pm - это только удобное соглашение. В рантайме можно создавать новые классы, без использования use - и у них не будет никакого соответствующего файла, который можно use'нуть.

Можете отнаследовать от сериализатора и грузить отсутствующие классы - но тогда учитывайте вышеописанные проблемы.

мне кажется обязан - если вы положили в сессию объект, то его вы и хотите получить назад. почему я должен думать как там сериализатор его хранит и восстанавливает? 
@INC в момент сохранения и восстановления совпадают

PS: добавил сточку eval "require ".ref($user); после получения объекта из сессии...
PM MAIL ICQ Jabber   Вверх
DurRandir
Дата 28.10.2009, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата
@INC в момент сохранения и восстановления совпадают

А сериализатор откуда это знает? Это не волшебная машинка smile

Цитата
почему я должен думать как там сериализатор его хранит и восстанавливает


Код

sub whatever{
        my ($class, $suffix) = @_;
        no strict 'refs';
        *{$class."::remove_$suffix"} = subname "remove_$suffix" => sub {
            my ($self, $key) = @_;
            delete $self->{$suffix}->{$key};
        };
}

whatever('Unexistant::Class', 'suffix);


Где сериализатору брать описание Unexistant::Class? smile

ЗЫ: строковый eval это плохо. Если заранее известно, объекты каких классов могут быть получены - лучше их загрузить через use в самом начале. Если не известно - то хотя бы не вызывать eval, если такой класс уже заружен.

Это сообщение отредактировал(а) DurRandir - 28.10.2009, 11:43
PM   Вверх
shamber
Дата 28.10.2009, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(DurRandir @  28.10.2009,  11:39 Найти цитируемый пост)
Если не известно - то хотя бы не вызывать eval, если такой класс уже заружен.

Вот вот, здесь на форуме, правда очень давно, пробегал такой способ загрузки модуля.
создавался хеш "загруженных модулей", если модуль уже там, то он не evalится. 
PM MAIL Jabber   Вверх
ADm
Дата 28.10.2009, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(DurRandir @  28.10.2009,  11:39 Найти цитируемый пост)
А сериализатор откуда это знает? Это не волшебная машинка smile

а зачем ему это знать? если модули в момент воостановления куда-то пропали или изменился INC - это проблема программиста

Цитата(DurRandir @  28.10.2009,  11:39 Найти цитируемый пост)
Где сериализатору брать описание Unexistant::Class? smile

ну а зачем так делать? правильней объявить класс а в нем метод remove который принимает в качестве параметра имя ключа хэша который надо удалить. кстати, что такое "subname"?

Цитата(DurRandir @  28.10.2009,  11:39 Найти цитируемый пост)
ЗЫ: строковый eval это плохо. Если заранее известно, объекты каких классов могут быть получены - лучше их загрузить через use в самом начале. Если не известно - то хотя бы не вызывать eval, если такой класс уже заружен.

интересно, а можно поподробней почему? и кстати внутри eval - require он то и проверяет загружен уже модуль или нет, разве нет?
PM MAIL ICQ Jabber   Вверх
DurRandir
Дата 28.10.2009, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата
что такое "subname"

Это из Sub::Name. Для профайлера/бэктрейсов - чтобы показывали не __ANON__, а "remove_smth"

Зачем таким образом? Мне удобнее вызывать не $obj->get('apples', 5), a  $obj->get_apples(5). Я могу использовать много разных ключей, и, при опечатке, я получу не пустое значение (или +код на проверку ключа), а автоматом - Undefined subroutine. Я могу создавать объекты с разными наборами ключей. Так что - удобство smile

Цитата
а зачем ему это знать

Ну так не мне надо, чтобы он загрузил "всё как было". Ему дали данные, он их и восстановил. Загрузить класс - это восстановить метаданные.

Цитата
поподробней

Два аспекта. Первое - безопасность

perl -e 'use Data::Dumper; $z=bless {}, "Good::Class; malicious_code"; print ref($z)'
..и в eval это) Входные данные не должны исполняться напрямую. По хорошему - вообще не должны исполняться, но это как получится.

Второе - строковый eval каждый раз вызывает разбор кода, который лежит в строчке - вызов парсера вещь очень недешевая. Да, require проверит, был ли файл загружен - но перед этим вызовом всё равно будет вызван парсер для eval'a.

Цитата
хеш "загруженных модулей"

Mагический хеш %INC smile

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


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

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


 




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


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

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