![]() |
Модераторы: korob2001, ginnie |
![]() ![]() ![]() |
|
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 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Perl" | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Perl: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |