![]() |
Модераторы: korob2001, ginnie |
![]() ![]() ![]() |
|
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Хотелось бы узнать, есть ли готовые решения для сабжа?
Я пробовал Class::Accessor, Class::Gomor, но не смог выжать из них то, что мне нужно. Ниже более подробное описание. Есть объект примерно такой структуры:
Мне нужен модуль, который бы автоматически сгенерировал следующие методы get'a/set'a:
Это сообщение отредактировал(а) KSURi - 4.1.2008, 19:51 -------------------- Died at Life.pl line 21 |
|||
|
||||
sir_nuf_nuf |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
стандартные модули - маловероятно... странный случай просто =) не думаю, что кому то могло такое понадобится.
если все таки надо, то можно делать так: тот самый модуль Class/Plainer.pm
примитивный тест test.pl
P.S. замечу, что а) под вложенными стурктурами понимаются только хеши хешей, т.е. содержимое массивов не просматривается б) как только идентификатор найден - поиск останавливается.. отсюда вывод: по хорошему _все_ имена полей класса должны быть различными - иначе задаче криво сформулирована Это сообщение отредактировал(а) sir_nuf_nuf - 6.1.2008, 07:31 |
||||
|
|||||
nitr |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2543 Регистрация: 10.2.2006 Где: Россия :) Репутация: 37 Всего: 84 |
sir_nuf_nuf, интересный подход, думаю это подталкнет на создание своего модуля, автора темы.
Тоже считаю, что модуля нет ещё для таких структур, хотя может авторы существующих, могут и подсказать. Лично не использовал, пишу все методы "ручками", и мне так удобнее, да и вполне это просто. Но суть мне интересна. З.Ы.: пожалуйста отредактируйте сообщение, используя подсветку кода, примерно так
так приятнее читать его. |
|||
|
||||
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Я прикидывал как это сделать самому (хотя ваш вариант кажется компактнее), просто думал может придется изобретать велосипед...
В любом случае спасибо, на досуге разберу ваш код -------------------- Died at Life.pl line 21 |
|||
|
||||
ginnie |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Уважаемый sir_nuf_nuf!
А как тест сработает в случае
![]() Это сообщение отредактировал(а) ginnie - 6.1.2008, 11:39 -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
|||
|
||||
sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
плохо сработает =)
меняем lookup
Спасибо за замечания !! Это сообщение отредактировал(а) sir_nuf_nuf - 7.1.2008, 22:29 |
|||
|
||||
ginnie |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Уважаемый sir_nuf_nuf, регулярное выражение
используется для ускорения работы? ![]() -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
|||
|
||||
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Зачем спорить по мелочам?) Выход тут очевиден я думаю, я вполне могу поправить те моменты, которые кажутся не совсем удачными.
-------------------- Died at Life.pl line 21 |
|||
|
||||
nitr |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2543 Регистрация: 10.2.2006 Где: Россия :) Репутация: 37 Всего: 84 |
В этом может родиться истина ;) Я думаю дискуссию можно не прекращать ![]() А может быть, что-то очень даже перспективное, главное нужное другим людям ;) , может получится. |
|||
|
||||
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Как я и говорил, на досуге взялся за код sir_nuf_nuf. Почитал, разобрал.
Вот проблема уже появилась: после вызова lookup для например ключа B в хэшерефе А (если смотреть абсолютно, то В выглядит как $obj->{A}->{B}, соответственно вызываю я его $obj->set_B('bla')), это ключ почему-то просто пропадает из этого самого хэшрефа (писать даже как-то стыдно такое, но что поделать...). Понимаю, что скорее всего ничего не понятно из данного текста, поэтому лучше посмотреть 3 скриншота (обратите внимание на красные рамки в верхнем-правом углу): 1. Структура hashref'a до вызова сеттера. http://i5.tinypic.com/6wxfakw.png 2. Структура hashref'a во время работы сеттера (если быть точным, то уже после работы оператора присваивания, но до возвращения из самого метода) http://i17.tinypic.com/6y504sj.png 3. Структура hasref'a после возвращения из сеттера http://i1.tinypic.com/870n1j9.png P.S.: sir_nuf_nuf, заметил что изменили немного код саба lookup, использовав прагму attributes и вместо ref использовали reftype. Можно узнать, чем вызвано такое решение? Это сообщение отредактировал(а) KSURi - 7.1.2008, 01:43 -------------------- Died at Life.pl line 21 |
|||
|
||||
ginnie |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Уважаемый KSURi, а нельзя модулем Data::Dumper вывести содержимое объекта после set__LoginTemplate(), чтобы исключить ошибки отладчика?
-------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
|||
|
||||
KSURi |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Сказать, что я удивлен, значит не сказать ничего...
Причем:
выдает
Это сообщение отредактировал(а) KSURi - 7.1.2008, 13:20 -------------------- Died at Life.pl line 21 |
||||||
|
|||||||
ginnie |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Уважаемый KSURi, руками бы уже раз 100 все методы доступа написал?
![]() Без твоих исходников, боюсь, никто ничего дельного не посоветует, я точно не смогу - у меня по телепатии двойка была в школе ![]() -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
|||
|
||||
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Дык написал уже давно, хотел вот объем кода сократить, а то получилось, что половина кода - однообразные сабы... -------------------- Died at Life.pl line 21 |
|||
|
||||
ginnie |
|
||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Уважаемый sir_nuf_nuf, решил еще раз внимательно посмотреть предложенный Вами вариант
![]() Возникло несколько моментов, требующих Ваших пояснений:
-------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
||||||
|
|||||||
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Ну вообще конструкция довольно распространенная...
Для обработки ситуаций, когда в скрипте вызывается не объявленный саб, можно написать "перехватчик" в виде саба AUTOLOAD. В переменной $AUTOLOAD будет храниться имя саба спровоцировавшего ошибку. Думаю вот эта конструкция все объяснит:
our использован для избежания ошибки "Global symbol $AUTOLOAD requires explicit package name" Это сообщение отредактировал(а) KSURi - 7.1.2008, 19:17 -------------------- Died at Life.pl line 21 |
|||
|
||||
ginnie |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Уважаемый KSURi, спасибо, что заставил прочитать документацию по функции AUTOLOAD (perldoc perltoot)!
![]() Раньше даже не подозревал, что
будет работать. Никогда не возникало желание так написать. Судя по документации, $AUTOLOAD - глобальная для модуля переменная и должна описываться в начале модуля, а никак не внутри функции AUTOLOAD(). Разве при выполнении программы интерпретатор не выдает ошибок о повторном использовании our? P.S. Кроме документации на AUTOLOAD пришлось еще прочитать документацию по our. P.P.S. KSURi, если это распространенная конструкция, попробуй сказать, как она работает (именно эта строчка, а не функция AUTOLOAD) и чем ее работа будет отличаться от
![]() Это сообщение отредактировал(а) ginnie - 7.1.2008, 19:49 -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
||||
|
|||||
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Желания так написать у меня тоже не было... Но факт работоспособности - на лицо)
Кстати, когда разбирал код sir_nuf_nuf, я изменил несколько строк в пользу своих привычек, в том числе момент с $AUTOLOAD. -------------------- Died at Life.pl line 21 |
|||
|
||||
sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
1) my $method = our $AUTOLOAD объявление лексической переменной =) этот прием называется - "замыкание" (подробнее http://perldoc.perl.org/perlref.html#Function-Templates или гугл по словам perl + closure или замыкание) P.S. our - не делает почти ничего, просто для того что бы use strict не давало ошибок. 2) *$method = sub {bla bla bla} запоминаем ссылку на созданную подпрограмму в таблице имен пакета по именем $method при следующем вызове этого же метода уже не будет AUTOLOAD, будет обычный вызов функции. своего рода кеширование. (подробнее http://perldoc.perl.org/perlmod.html#Symbol-Tables) |
|||
|
||||
sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
да.. lookup переживает изменения, лучше постоянно смотерть последнюю версию причина переход ref -> reftype ref показывает имя класса для bless - нутых сылок например
и ( как показывают эксперименты =)) reftype не переваривает не-ссылки. Это сообщение отредактировал(а) sir_nuf_nuf - 7.1.2008, 22:18 |
|||
|
||||
KSURi |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Такая конструкция не будет работать. Переменная my $AUTOLOAD не будет иметь никакого отношения к AUTOLOAD, а будет простой переменной. На всякий случай, повторю, что
Добавлено через 4 минуты и 19 секунд
А вот этого не знал, спасибо Это сообщение отредактировал(а) KSURi - 7.1.2008, 22:15 -------------------- Died at Life.pl line 21 |
||||
|
|||||
ginnie |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Уважаемый sir_nuf_nuf, спасибо за ссылки на документацию! Я ее люблю почитать, жалко в голове не все остается
![]() Продолжим разбирательства: 1. Про объявление лексической переменной $method все верно. Вопрос в том, какое значение мы ей присваиваем? Если our не написать, интерпретатор сообщает, что $AUTOLOAD нигде не описана. Чтобы убрать ошибку, надо $AUTOLOAD описать. Здесь вариантов три: my, local и our. Пишем our, ошибка пропала, все работает. А теперь, внимание, вопрос: имя вызываемой функции в переменную $AUTOLOAD записывается до вызова функции AUTOLOAD, как это происходит, если описана переменная $AUTOLOAD внутри функции AUTOLOAD? Я не издеваюсь, сам тоже точно не знаю, хочу разобраться (есть мысль, что это дело рук оптимизатора). Все, что Вы написали про closure к первому пункту отношения не имеет, оно для второго пункта. 2. Здесь Вы все прояснили, спасибо, все уже подзабыл про таблицу символов модуля. Осталось только два замечания: в конце
лучше ставить ; и зачем Вы использовали goto(). Кстати про closure понятнее написано в Perl FAQ 3.14. 3. С reftype() Вы зря переделали. Если в структуре хранится объект, то писать функции доступа к его параметрам это плохой стиль, т.к. объект сам должен их предоставлять. Это сообщение отредактировал(а) ginnie - 7.1.2008, 23:02 -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
|||
|
||||
sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
продолжим...
1) кхм.. мое видение дела: our не создает ни новую переменную ( как делает my) ни новое значение глобальной переменной ( как делает Local) our просто говорит компилятору, что $AUTOLOAD - есть глобальная переменная, если такая переменная уже есть - она и используется. our необходима только при использовании use strict - дабы заткнуть компилятор, ну или убедить его что мы знаем что делаем =) без use strict можно было бы писать my $meth = $AUTOLOAD; 2) goto &$method - это вызов только что созданного нами метода не забываем, что вызывает getter пользователь хотел получить значение переменной, а не просто создать getter ![]() почему через goto ? да вот сложно сказать... говорят оптимизация =) (говорят тут: http://perldoc.perl.org/functions/goto.html) return $method->(@_); тоже срабатывает 3) reftype vs ref... ну я ничего не навязываю ![]() Добавлено через 1 минуту и 5 секунд Уважаемый KSURi, я не заметил пропадения ключей из хешей.. все работает. может действительно проблемы дебагера ? |
|||
|
||||
ginnie |
|
||||||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 1287 Регистрация: 6.1.2008 Где: Москва Репутация: 38 Всего: 49 |
Уважаемый sir_nuf_nuf, продолжаем
![]() 1.
а что Вы на это скажите?
2.
Спасибо, узнал много нового про goto() ![]() Возник еще вопрос, косьвенно связанный с Вашим решением: Предположим мы описали класс Parent как в Вашем варианте. Создаем класс-наследник Child. В нем описываем параметр param_x, которого нет в родительском классе. Создаем объект $child_object класса Child и вызываем метод $child_object->get_param_x(). Вопрос: в таблице символов какого класса сохранится ссылка на функцию get_param_x()? -------------------- Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг) |
||||||||
|
|||||||||
sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
1) я на это уже говорил несколько раз.
our как раз и сделана для того что бы избегать вот этого вот:
читай сюда внимательно: http://perldoc.perl.org/functions/our.html our говорит компилятору, что глобальная переменная которую мы юзаем принадлежит текущему пакету. вообще поумолчанию так всегда и есть. но когда включаем strict - надо еще раз в это убедиться =) 2) интересно... вообще пока не могу ответить на этот вопрос - исследую ... Добавлено через 13 минут и 36 секунд по поводу 2) ссылки на все геттеры сохраняются в таблице имен класса Class::Plainer. однако, в таблице имен всех его дочерних классов также появятся ссылки на соответсвующую подпрограмму, но это делаем уже не мы, а perl т.е. как только вы вызываете (в первый раз) метод который объект наследует от кого-то то в таблице имен класса вашего объекта появится новая запись =) при последующих вызовах perl уже не будет просматривать ISA иерархию.. P.S. запросто могу ошибаться. хм... а стоит ли здесь это обсуждать ? ![]() |
|||
|
||||
nitr |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2543 Регистрация: 10.2.2006 Где: Россия :) Репутация: 37 Всего: 84 |
KSURi, я так думаю можно в раздел "Исходники" бросить код, который мы будем "модифицировать" ;) все вместе. А для кого-то они будут очень даже ;)
P.S.: хоть какая-то база будет составляться... |
|||
|
||||
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
К сожалению не могу выложить пока исходники целиком. Чувствую, что сам обязан разобраться в ситуации.
После исправления багов обещаю выложить) -------------------- Died at Life.pl line 21 |
|||
|
||||
tishaishii |
|
|||
![]() Создатель ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1262 Регистрация: 14.2.2006 Где: Москва Репутация: 4 Всего: 8 |
Это сообщение отредактировал(а) tishaishii - 11.1.2008, 18:46 |
|||
|
||||
sir_nuf_nuf |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 920 Регистрация: 6.1.2008 Репутация: 14 Всего: 31 |
tishaishii, можно поинтересоваться, зачем вам
унарные плюсы нужны ? конкретнее зачем они нужны именно в этой ситуации ? coding style ? |
|||
|
||||
shamber |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1422 Регистрация: 5.9.2006 Где: Россия Репутация: 17 Всего: 18 |
sir_nuf_nuf, если вы посмотрите другие посты
tishaishii, то вы поймете. Ваша догадка про style верна ![]() Это сообщение отредактировал(а) shamber - 12.1.2008, 16:11 |
|||
|
||||
tishaishii |
|
|||
![]() Создатель ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1262 Регистрация: 14.2.2006 Где: Москва Репутация: 4 Всего: 8 |
Кому что не нравится как работает, пишите. Если не нравятся плюсы - уберите их и пользуйтесь себе спокойно.
|
|||
|
||||
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Жаль писать, но пока не подтолкнул(( Рабочий скрипт нужен был, а времени мало было, чтобы придумывать и писать модуль. Однако как разберусь с сессией - возьмусь снова наверное) Собственно проблема была решена через редизайн объекта (убрал сложные структуры). P.S.: обсуждал тему на другом форуме, там люди тоже предложили несколько вариантов, и там же мне посоветовали изменить структуру объекта. Читайте, кому интересно. Это сообщение отредактировал(а) KSURi - 23.1.2008, 22:07 -------------------- Died at Life.pl line 21 |
|||
|
||||
gcc |
|
|||
![]() Агент алкомафии ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2691 Регистрация: 25.4.2008 Где: %&й Репутация: 1 Всего: 17 |
KSURi, ради интереса: скажите что вы выбрали?
и в чем была пролема? почему нельзя написать классы set get и их использовать (и между ними наследовать и т.д.) или в структуры ссылки написать, потом передрать?? |
|||
|
||||
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Тогда поменял структуру объекта, убрав вложенные хэшрефы. Примерно пару месяцов назад я снова наткнулся на эту тему, так получился Class::Accessor::Deep (доступен на CPAN).
Проблема описана в первом посте темы. Честно говоря, не очень понял, что вы имели ввиду. Это сообщение отредактировал(а) KSURi - 18.7.2009, 01:05 -------------------- Died at Life.pl line 21 |
|||
|
||||
gcc |
|
|||
![]() Агент алкомафии ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2691 Регистрация: 25.4.2008 Где: %&й Репутация: 1 Всего: 17 |
KSURi, интерфейс программы не совсем понял... зачем все это?
Это сообщение отредактировал(а) gcc - 18.7.2009, 01:10 |
|||
|
||||
KSURi |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 887 Регистрация: 8.6.2006 Где: Russia Репутация: 20 Всего: 27 |
Чтобы не плодить методы типа get_a, get_b, ..., не делать $self->{hashref1}->{hashref2}->{a}, $self->{hashref1}->{hashref2}->{b}.
-------------------- Died at Life.pl line 21 |
|||
|
||||
gcc |
|
|||
![]() Агент алкомафии ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2691 Регистрация: 25.4.2008 Где: %&й Репутация: 1 Всего: 17 |
понятно, кажется понял...
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "Perl" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |