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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Генератор accessor'ов, Генератор методов доступа для сложных структур внутри объекта 
:(
    Опции темы
KSURi
Дата 7.1.2008, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ну вообще конструкция довольно распространенная...
Для обработки ситуаций, когда в скрипте вызывается не объявленный саб, можно написать "перехватчик" в виде саба AUTOLOAD. В переменной $AUTOLOAD будет храниться имя саба спровоцировавшего ошибку. Думаю вот эта конструкция все объяснит:
Код

C:\>perl -e "nosuchsub();sub AUTOLOAD {};print $AUTOLOAD"
main::nosuchsub
C:\>

our использован для избежания ошибки "Global symbol $AUTOLOAD requires explicit package name"

Это сообщение отредактировал(а) KSURi - 7.1.2008, 19:17


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ginnie
Дата 7.1.2008, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



Уважаемый KSURi, спасибо, что заставил прочитать документацию по функции AUTOLOAD (perldoc perltoot)! smile

Раньше даже не подозревал, что
Код

my $method = our $AUTOLOAD;

будет работать. Никогда не возникало желание так написать. Судя по документации, $AUTOLOAD - глобальная для модуля переменная и должна описываться в начале модуля, а никак не внутри функции AUTOLOAD(). Разве при выполнении программы интерпретатор не выдает ошибок о повторном использовании our?

P.S. Кроме документации на AUTOLOAD пришлось еще прочитать документацию по our.

P.P.S. KSURi, если это распространенная конструкция, попробуй сказать, как она работает (именно эта строчка, а не функция AUTOLOAD) и чем ее работа будет отличаться от
Код

my $method = my $AUTOLOAD;
  smile 

Это сообщение отредактировал(а) ginnie - 7.1.2008, 19:49


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 7.1.2008, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Желания так написать у меня тоже не было... Но факт работоспособности - на лицо)
Кстати, когда разбирал код sir_nuf_nuf, я изменил несколько строк в пользу своих привычек, в том числе момент с $AUTOLOAD.


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
sir_nuf_nuf
Дата 7.1.2008, 20:43 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(ginnie @  7.1.2008,  17:30 Найти цитируемый пост)
для чего? Разве без "выкрутасов" не будет работать?


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)




--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
sir_nuf_nuf
Дата 7.1.2008, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(KSURi @  7.1.2008,  01:42 Найти цитируемый пост)
B в хэшерефе 


да.. lookup переживает изменения, лучше постоянно смотерть последнюю версию

причина переход ref -> reftype
ref показывает имя класса  для bless - нутых сылок
например
Код

package Boom;
use attributes qw(reftype);
$r = bless {};
print ref $r;  # will print "Boom"
print reftype $r; #will print "HASH"


и ( как показывают эксперименты =)) 
reftype не переваривает не-ссылки.


Это сообщение отредактировал(а) sir_nuf_nuf - 7.1.2008, 22:18


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
KSURi
Дата 7.1.2008, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(ginnie @  7.1.2008,  19:37 Найти цитируемый пост)
P.P.S. KSURi, если это распространенная конструкция, попробуй сказать, как она работает (именно эта строчка, а не функция AUTOLOAD) и чем ее работа будет отличаться от
Код

my $method = my $AUTOLOAD;

Такая конструкция не будет работать. Переменная my $AUTOLOAD не будет иметь никакого отношения к AUTOLOAD, а будет простой переменной.

На всякий случай, повторю, что
Цитата(KSURi @  7.1.2008,  19:02 Найти цитируемый пост)
our использован для избежания ошибки "Global symbol $AUTOLOAD requires explicit package name"


Добавлено через 4 минуты и 19 секунд
Цитата(sir_nuf_nuf @  7.1.2008,  20:43 Найти цитируемый пост)
2) *$method = sub {bla bla bla}
запоминаем ссылку на созданную подпрограмму в таблице имен пакета по именем $method
при следующем вызове этого же метода уже не будет AUTOLOAD, будет обычный вызов функции.
своего рода кеширование.
(подробнее http://perldoc.perl.org/perlmod.html#Symbol-Tables)

А вот этого не знал, спасибо

Это сообщение отредактировал(а) KSURi - 7.1.2008, 22:15


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ginnie
Дата 7.1.2008, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



Уважаемый sir_nuf_nuf, спасибо за ссылки на документацию! Я ее люблю почитать, жалко в голове не все остается  smile

Продолжим разбирательства:

1. Про объявление лексической переменной $method все верно. Вопрос в том, какое значение мы ей присваиваем? Если our не написать, интерпретатор сообщает, что $AUTOLOAD нигде не описана. Чтобы убрать ошибку, надо $AUTOLOAD описать. Здесь вариантов три: my, local и our. Пишем our, ошибка пропала, все работает. А теперь, внимание, вопрос: имя вызываемой функции в переменную $AUTOLOAD записывается до вызова функции AUTOLOAD, как это происходит, если описана переменная $AUTOLOAD внутри функции AUTOLOAD? Я не издеваюсь, сам тоже точно не знаю, хочу разобраться (есть мысль, что это дело рук оптимизатора).
Все, что Вы написали про closure к первому пункту отношения не имеет, оно для второго пункта.

2. Здесь Вы все прояснили, спасибо, все уже подзабыл про таблицу символов модуля. Осталось только два замечания:
в конце
Код

       *$method = sub {
            my ($self) = @_;
            return ${lookup($self, $iden)};
        }

лучше ставить ;

и зачем Вы использовали goto().

Кстати про closure понятнее написано в Perl FAQ 3.14.

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

Это сообщение отредактировал(а) ginnie - 7.1.2008, 23:02


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
sir_nuf_nuf
Дата 7.1.2008, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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  smile 

почему через goto ? да вот сложно сказать... говорят оптимизация =)
(говорят тут: http://perldoc.perl.org/functions/goto.html)

return $method->(@_);  тоже срабатывает

3) reftype vs ref... ну я ничего не навязываю  smile

Добавлено через 1 минуту и 5 секунд
Уважаемый KSURi
я не заметил пропадения ключей из хешей.. все работает. может действительно проблемы дебагера ?


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
ginnie
Дата 7.1.2008, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

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



Уважаемый sir_nuf_nuf, продолжаем  smile

1. 
Цитата
our просто говорит компилятору, что $AUTOLOAD - есть глобальная переменная, если такая переменная уже есть - она и используется.

а что Вы на это скажите?
Код

use strict;
use warnings;

$test = 12;
our $test;

print $test;


Код

Global symbol "$test" requires explicit package name at test.pl line 4.
Execution of test.pl aborted due to compilation errors.


2. 
Цитата

говорят оптимизация

Спасибо, узнал много нового про goto()  smile, только про оптимизацию, как я ее понимаю, там ни слова нет.

Возник еще вопрос, косьвенно связанный с Вашим решением:
Предположим мы описали класс Parent как в Вашем варианте. Создаем класс-наследник Child. В нем описываем параметр param_x, которого нет в родительском классе.
Создаем объект $child_object класса Child и вызываем метод $child_object->get_param_x(). Вопрос: в таблице символов какого класса сохранится ссылка на функцию get_param_x()?



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
sir_nuf_nuf
Дата 8.1.2008, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



1) я на это уже говорил несколько раз. 
our как раз и сделана для того что бы избегать вот этого вот:
Код

Global symbol "$test" requires explicit package name at test.pl line 4.
Execution of test.pl aborted due to compilation errors.


читай сюда внимательно: http://perldoc.perl.org/functions/our.html

our говорит компилятору, что глобальная переменная которую мы юзаем принадлежит текущему пакету.
вообще поумолчанию так всегда и есть. но когда включаем strict - надо еще раз в это убедиться =)

2) интересно...
вообще пока не могу ответить на этот вопрос  - исследую ...

Добавлено через 13 минут и 36 секунд
по поводу 2)
ссылки на все геттеры сохраняются  в таблице имен 
класса Class::Plainer.

однако, в таблице имен всех его дочерних классов также появятся ссылки на
соответсвующую подпрограмму, но это делаем уже не мы, а perl

т.е. как только вы вызываете (в первый раз) метод который объект наследует от кого-то
то в таблице имен класса вашего объекта появится новая запись =)
при последующих вызовах perl уже не будет просматривать ISA иерархию..

P.S. запросто могу ошибаться.

хм... а стоит ли здесь это обсуждать ?  smile 


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
nitr
Дата 8.1.2008, 04:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



KSURi, я так думаю можно в раздел "Исходники" бросить код, который мы будем "модифицировать" ;) все вместе. А для кого-то они будут очень даже ;) 

P.S.: хоть какая-то база будет составляться...


--------------------
PM   Вверх
KSURi
Дата 8.1.2008, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



К сожалению не могу выложить пока исходники целиком. Чувствую, что сам обязан разобраться в ситуации.
После исправления багов обещаю выложить)


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
tishaishii
Дата 11.1.2008, 18:45 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Создатель
***


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

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



Код
package Hash;

sub FIT {+$_[1]=ref $_[1] eq 'HASH' ? tie %{$_[1]}, __PACKAGE__, %{$_[1]} : $_[1]}
sub WALK {
    my($class, $hash)=(shift, shift);
    $class->FIT($_) foreach values %$hash;
    +$hash
}
sub TIEHASH {
    my($class, $hash)=(shift, {@_});
    +bless($hash, $class)->WALK($hash)
}
sub FIRSTKEY {reset %{$_[0]};+(each %{$_[0]})[0]}
sub STORE {$_[0]->FIT($_[0]{$_[1]}=$_[2])}
sub FETCH {+$_[0]{$_[1]} if $_[0]->EXISTS($_[1])}
sub CLEAR {%{$_[0]}=()}
sub EXISTS {+exists $_[0]{$_[1]}}
sub DELETE {+delete $_[0]{$_[1]}}
sub AUTOLOAD {+shift->FETCH(+(split '::', $AUTOLOAD)[-1])}
sub DESTROY {}

package main;

my%hash=(
    A=>{
        B=>C
    }
);
print Hash->FIT(\%hash)->A->B;


Это сообщение отредактировал(а) tishaishii - 11.1.2008, 18:46
PM MAIL ICQ Skype   Вверх
sir_nuf_nuf
Дата 11.1.2008, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



tishaishii, можно поинтересоваться, зачем вам 
унарные плюсы нужны ?

конкретнее зачем они нужны именно в этой ситуации ?
coding style ?


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
shamber
Дата 12.1.2008, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



sir_nuf_nuf, если вы посмотрите другие посты 
tishaishii, то вы поймете.
Ваша догадка про style верна smile

Это сообщение отредактировал(а) shamber - 12.1.2008, 16:11
PM MAIL Jabber   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


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

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


 




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


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

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