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

Поиск:

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


Опытный
**


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

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



Хотелось бы узнать, есть ли готовые решения для сабжа?
Я пробовал Class::AccessorClass::Gomor, но не смог выжать из них то, что мне нужно.
Ниже более подробное описание.

Есть объект примерно такой структуры:
Код

...
$self = {
    Hash => {
        A => 1,
        B => 2,
        # etc.
    },
    Array => [qw(1 2 3)],
    Scalar => 'bla'
}
...

Мне нужен модуль, который бы автоматически сгенерировал следующие методы get'a/set'a:
  • Hash
  • A
  • B
  • Array
  • Scalar
Т.е. мне нужен генератор для аттрибутов, у которых уровень вложенности больше 1. Надесь суть ясна.

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


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


Опытный
**


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

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



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

тот самый модуль Class/Plainer.pm

Код

package Class::Plainer;
use base qw(Exporter);
use strict;

our @EXPORT_OK = qw(AUTOLOAD);

sub lookup
{
    my ($hr, $iden) = @_;
    return \$hr->{$iden} if exists $hr->{$iden};
    foreach (values %$hr) {
        if (/HASH/) {
            return lookup($_, $iden);
        }
    }
    return;
}

sub AUTOLOAD
{
    no strict 'refs';
    my $method = our $AUTOLOAD;
    $method =~ s/.*:://;
    if ($method =~ m/get_?(\w+)/) {
        my $iden = $1;
        *$method = sub {
            my ($self) = @_;
            return ${lookup($self, $iden)};
        }
    } elsif ($method =~ m/set_?(\w+)/) {
        my $iden = $1;
        *$method = sub {
            my ($self, $val) = @_;
            ${lookup($self, $iden)} = $val;
        }
    } else {
        die "not a get/set $method";
    }
    goto &$method;
}
1;


примитивный тест test.pl

Код

package Test;
use base qw(Class::Plainer);
sub new
{
    my $self = {
        Hash => {
            A => 1,
            B => 2,
            # etc
        },
        Array => [qw(1 2 3)],
        Scalar => 'bla'
    };
    bless $self, shift;
    return $self;
}

package main;
$instance = Test::->new();

print $instance->get_Array(), "\n";
print $instance->get_Scalar(), "\n";
print $instance->set_Scalar('alb'), "\n";
print $instance->get_Scalar(), "\n";
print $instance->get_Hash(), "\n";
print $instance->get_A(), "\n";
$instance->set_Hash({chunga => changa});
print $instance->get_chunga(), "\n";


P.S. замечу, что
а) под вложенными стурктурами понимаются только хеши хешей, т.е. содержимое массивов не просматривается
б) как только идентификатор найден - поиск останавливается.. отсюда вывод:
по хорошему _все_ имена полей класса должны быть различными - иначе задаче криво сформулирована

Это сообщение отредактировал(а) sir_nuf_nuf - 6.1.2008, 07:31


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


Эксперт
****


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

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



sir_nuf_nuf, интересный подход, думаю это подталкнет на создание своего модуля, автора темы.
Тоже считаю, что модуля нет ещё для таких структур, хотя может авторы существующих, могут и подсказать.
Лично не использовал, пишу все методы "ручками", и мне так удобнее, да и вполне это просто.
Но суть мне интересна.

З.Ы.: пожалуйста отредактируйте сообщение, используя подсветку кода, примерно так
Код

#!/usr/bin/perl

так приятнее читать его.


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


Опытный
**


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

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



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


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


Эксперт
***


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

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



Уважаемый sir_nuf_nuf!

А как тест сработает в случае
Код

    my $self = {
        Hash => {
            A => 1,
            B => 2,
            # etc
        },
        Array => [qw(1 2 3)],
        Scalar => 'HASHING',
    };

 smile 

Это сообщение отредактировал(а) ginnie - 6.1.2008, 11:39


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


Опытный
**


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

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



плохо сработает =)
меняем lookup

Код


sub lookup
{
    use attributes qw(reftype);
    my ($hr, $iden) = @_;
    return \$hr->{$iden} if exists $hr->{$iden};
    foreach (values %$hr) {
        if (ref($_) and reftype($_) =~ /HASH/) {
            return lookup($_, $iden);
        }
    }
    return;
}



Спасибо за замечания !!

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


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


Эксперт
***


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

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



Уважаемый sir_nuf_nuf, регулярное выражение
Код

ref $_ =~ /HASH/ 

используется для ускорения работы?  smile 


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


Опытный
**


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

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



Зачем спорить по мелочам?) Выход тут очевиден я думаю, я вполне могу поправить те моменты, которые кажутся не совсем удачными.


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


Эксперт
****


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

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



Цитата(KSURi @  6.1.2008,  13:58 Найти цитируемый пост)
Зачем спорить по мелочам?)

В этом может родиться истина ;)

Я думаю дискуссию можно не прекращать smile , интересная тема.
А может быть, что-то очень даже перспективное, главное нужное другим людям ;) , может получится.


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 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
PM Jabber   Вверх
ginnie
Дата 7.1.2008, 02:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Уважаемый KSURi, а нельзя модулем Data::Dumper вывести содержимое объекта после set__LoginTemplate(), чтобы исключить ошибки отладчика?


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


Опытный
**


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

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



Сказать, что я удивлен, значит не сказать ничего...
Код

$VAR1 = bless( {
                 'ProtoData' => {
                                  '_LoginData' => {
                                                    '__LoginFailure' => undef,
                                                    '__LoginSuccess' => '220', # заполнилось
                                                    '__LoginTemplate' => 'USER {USER}
PASS {PASS}
', # заполнилось
                                                    '__LoginUser' => 'test', # заполнилось
                                                    '__LoginPass' => 'test' # заполнилось
                                                  },
                                  '_ActionData' => {
                                                     '__ActionExit' => undef, # не заполнилось
                                                     '__ActionTemplate' => undef, # не заполнилось
                                                     '__ActionCmd' => [] # не заполнилось
                                                   }
                                },
...

Причем:
Код

print join("\n", $t->get___LoginTemplate,
                           $t->get___LoginUser,
                           $t->get___LoginPass,
                           $t->get___LoginSuccess,
                           $t->get___ActionCmd,
                           $t->get___ActionTemplate,
                           $t->get___ActionExit);
exit;

выдает
Код

QUIT
QUIT
QUIT
QUIT
QUIT
QUIT
QUIT


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


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


Эксперт
***


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

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



Уважаемый KSURi, руками бы уже раз 100 все методы доступа написал? smile

Без твоих исходников, боюсь, никто ничего дельного не посоветует, я точно не смогу -  у меня по телепатии двойка была в школе  smile 


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


Опытный
**


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

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



Цитата(ginnie @  7.1.2008,  15:37 Найти цитируемый пост)
Уважаемый KSURi, руками бы уже раз 100 все методы доступа написал? smile

Дык написал уже давно, хотел вот объем кода сократить, а то получилось, что половина кода - однообразные сабы...


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


Эксперт
***


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

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



Уважаемый sir_nuf_nuf, решил еще раз внимательно посмотреть предложенный Вами вариант  smile
Возникло несколько моментов, требующих Ваших пояснений:
  • первый раз сталкиваюсь с конструкцией
    Код

    my $method = our $AUTOLOAD;

    что она делает?
  • нетривиальная конструкция 
    Код

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

    для чего? Разве без "выкрутасов" не будет работать?
    Код

    return ${lookup($self, $iden)};



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
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   Вверх
tishaishii
Дата 16.1.2008, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Кому что не нравится как работает, пишите. Если не нравятся плюсы - уберите их и пользуйтесь себе спокойно.
PM MAIL ICQ Skype   Вверх
KSURi
Дата 23.1.2008, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(nitr @  6.1.2008,  01:07 Найти цитируемый пост)
sir_nuf_nuf, интересный подход, думаю это подталкнет на создание своего модуля, автора темы.

Жаль писать, но пока не подтолкнул(( Рабочий скрипт нужен был, а времени мало было, чтобы придумывать и писать модуль. Однако как разберусь с сессией - возьмусь снова наверное)

Собственно проблема была решена через редизайн объекта (убрал сложные структуры).

P.S.: обсуждал тему на другом форуме, там люди тоже предложили несколько вариантов, и там же мне посоветовали изменить структуру объекта. Читайте, кому интересно.

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


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


Агент алкомафии
****


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

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



KSURi, ради интереса: скажите что вы выбрали?
 и в чем была пролема?
почему нельзя написать классы set get и их использовать (и между ними наследовать и т.д.) или в структуры ссылки написать, потом передрать??
PM WWW ICQ Skype GTalk Jabber   Вверх
KSURi
Дата 18.7.2009, 01:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Тогда поменял структуру объекта, убрав вложенные хэшрефы. Примерно пару месяцов назад я снова наткнулся на эту тему, так получился Class::Accessor::Deep (доступен на CPAN).
Проблема описана в первом посте темы.
Честно говоря, не очень понял, что вы имели ввиду.

Это сообщение отредактировал(а) KSURi - 18.7.2009, 01:05


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


Агент алкомафии
****


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

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



KSURi, интерфейс программы не совсем понял... зачем все это?

Это сообщение отредактировал(а) gcc - 18.7.2009, 01:10
PM WWW ICQ Skype GTalk Jabber   Вверх
KSURi
Дата 18.7.2009, 01:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 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
PM Jabber   Вверх
gcc
Дата 18.7.2009, 01:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Агент алкомафии
****


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

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



понятно, кажется понял...
PM WWW ICQ Skype GTalk 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.1483 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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