Модераторы: 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   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


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

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


 




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


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

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