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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Классы, работа с данными 
:(
    Опции темы
Bulat
Дата 14.11.2007, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


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

Репутация: 5
Всего: 57



В целом, тема очень широкая, и появились еще дополнительные вопросы... Вообще конечно, кое-что уже было разъяснено ;) однако я сам не с того конца сформулировал вопрос, поэтому и не получил все ответы на него...

В целом получится может даже убить два зайца...

Изначально был очень хороший, но все же тривиальный пример... А меня сейчас интересует нечто более глубже... В данном примере, все поля класса - хеши, у класса есть свои методы и т.п. Все это хорошо, но если нам нужно что-то более сложноструктурированное, чтоб допустим этот класс, являлся лишь полем какого-то другого класса... И при этом из нового класса, доступ ко всем методам класса текущего, получается что-то типа наследования... Если не представится сложным, хотелось также затронуть момент переопределения метода, и для разнообразия побольше функциональных действий в самом конструкторе...

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

./myScript.pl - <корневой скрипт>
./myClasses/... - пакет, где находятся классы, допустим
    ./myClasses/classesForDB/...
    ./myClasses/classesForFiles/...
    ./myInterfaces/....
./myUtils/... - также содержатся какие-то классы
./myModules/... - просто модули
./files/... - пакет просто для каких-то конфигов, xml-файлов, или еще чего-нить
...

Для знатока явы, я думаю понятно, что я хотел спросить про пакеты и подпакеты smile


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
vadiml
Дата 18.11.2007, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 5
Всего: 7



> чтоб допустим этот класс, являлся лишь полем какого-то другого класса

создаешь переменную в классе и этой переменной присваиваешь класс, т.к. класс в перле это всего лишь blessed ссылка (или array, ...)

> хотелось также затронуть момент переопределения метода, 

для переопределения метода базового класса вообще ни чего не надо делать -- поиск метода всегда начинается с пространства имен текущего класса и только если ни чего не нашлось, то потом поочереди перебирается дерево базовых классов.

другое дело если надо в классе переопределить встроенный в перл метод -- в начале класса надо объявить эту функцию, например переопределение split:
use subs qw(split);
а уже ниже её описать.
экспортировать такую функцию не советую, путь живёт в пространстве имен только этого класса

> побольше функциональных действий в самом конструкторе...

в конструкторе можно делать что угодно, это самая обычная функция, которую и обозвать можно как угодно, например в Tk принято конструктору давать имя класса, хотя наиболее частый вариант -- это new

> как лучше работать с директориями(пакетами), куда можно объеденить несколько классов

создать для них каталог, например QQQ, и потом подключать их как
use QQQ::модуль1;
use QQQ::модуль2;

но и названия пакетов внутри тоже должны быть приведены к этому виду:
package QQQ::пакет1;
use 5.008;
use strict;

use QQQ::модуль2;
...

ЗЫ посмотри любой каталог, где лежат модули перла

PM MAIL Jabber   Вверх
Bulat
Дата 20.11.2007, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


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

Репутация: 5
Всего: 57



Цитата(vadiml @  18.11.2007,  18:18 Найти цитируемый пост)
создать для них каталог, например QQQ, и потом подключать их как
use QQQ::модуль1;
use QQQ::модуль2;

но и названия пакетов внутри тоже должны быть приведены к этому виду:
package QQQ::пакет1;
use 5.008;
use strict;

use QQQ::модуль2;


Все же не совсем понял, а именно

use QQQ::модуль1;
package QQQ::пакет1;
use QQQ::модуль2;

тривиальный пример

есть два модуля: util.pm и work.pm, что и где должно прописатся чтобы можно было работать при структуре

./mainScript.pl
./modules/util.pm
./modules/work.pm

Но меня, интересует как бы не только раскидал по директориям и работаешь из основного скрипта... Но и такие ситуации, что модули из одного подкаталога должны использовать процедуры или модули из другого подкаталога... Конечно можно все это писать ручками в самих скриптах, указывая пути, но хотелось бы что-то более оптимальное, чтоб при работе, при подключении модулей, он просматривал корневой каталог текущего проекта, а там дальше по подкаталогам и к нужнему конфигу или модулю...

Пример конечно не плохой, но уж слишком "на пальцах" smile


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
Bulat
Дата 20.11.2007, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


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

Репутация: 5
Всего: 57



Хм...

Что касается пакетов, то частично решил свои задачи, правда не могу пока знать все плюсы и минусы подобного подхода, надеюсь подскажете

модуль

Код

#!/usr/bin/perl

package modules::printDatas;

use strict;

BEGIN {

    use Exporter ();

    our @ISA = 'Exporter';
    our @EXPORT;

    push @EXPORT , '&PrintHeader';
    push @EXPORT , '&PrintFooter';
    push @EXPORT , '&PrintMainLinks';
}

sub PrintHeader {
    print (qq{
        <html>
            <head>
                <title>File Uploader</title>
                <meta http-equiv="content-type" content="text/html; charset=utf-8">
            </head>
            <body>
    });
}

sub PrintMainLinks {
    print (qq{
        <br>
            <div align = "right">
                <h4>
                    <a href = "/servers/">Show servers list</a>
                </h4>
            </div>
        <br>
    });
}

sub PrintFooter {
    print (qq{
            </body>
        </html>
    });
}

sub PrintServersList {
}

1;

END { };


соотв в самом скрипте достаточно подключить его use modules::printDatas, а для вызова процедуры достаточно PrintHeader допустим, но здесь у меня возник еще один вопрос. В модуле я ручками прописываю     push @EXPORT , '&PrintHeader';, но если уже есть хотелось бы, чтоб это выполнялось для всех процедур, которые есть в модуле... Конечно можно и ручками придумать нечто подобное, но если велосипед изобрели до меня smile


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
vadiml
Дата 23.11.2007, 23:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 5
Всего: 7



Для экспорта должен быть резон
Иногда гораздо читабельне вызывать функции по полному имени:
modules::printDatas::PrintHeader();
или для чего-то с зависимым содержанием создали класс, а потом вызывали через его указатель функции:
my $pd = printDatas::new();
$pd->PrintHeader();

А если Вам хочется заняться экспортом, то надо заметить, что экспортироваться могут не только функции, но и любые переменные, массивы, хеши.
а 
our @EXPORT;
push @EXPORT , '&PrintHeader';
... # куча push
проще описать как 
our @EXPORT = qw(PrintHeader PrintFooter PrintMainLinks);
не забывайте про списковый контекст, это часто очень удобный способ передачи данных

PS вообще плохой пример с названием modules, желательно что-то осмысленное. В лучше бы Вы подключили каталог modules в переменную просмотра путей для поиска модулей:
use lib qw(ваш_путь/modules ещё_один_путь_к_другой_группе_модулей);
use printDatas;
...
printDatas::PrintHeader();

PPS пустой блок END { } не имеет смысла, как и BEGIN стоящий в самом начале файла -- код в нем и так выполнится первым.
Главное чтоб Вы модули подключали через use, а не require, при первом способе компиляция выполняется при старте программы, при втором -- при обращении к ней.
PM MAIL Jabber   Вверх
Bulat
Дата 25.11.2007, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


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

Репутация: 5
Всего: 57



Цитата(vadiml @  23.11.2007,  23:50 Найти цитируемый пост)
Для экспорта должен быть резон
Иногда гораздо читабельне вызывать функции по полному имени:

Резон-то есть... Методы(процедуры) вызываются в основном скрипте, это все ж не просто классы экземпляры данных smile


Цитата(vadiml @  23.11.2007,  23:50 Найти цитируемый пост)
проще описать как 
our @EXPORT = qw(PrintHeader PrintFooter PrintMainLinks);


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


Цитата(vadiml @  23.11.2007,  23:50 Найти цитируемый пост)
PPS пустой блок END { } не имеет смысла, как и BEGIN стоящий в самом начале файла -- код в нем и так выполнится первым.


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



--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
Bulat
Дата 15.9.2009, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


татарский Нео
***


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

Репутация: 5
Всего: 57



некромантирую свою старую тему. smile

Хотелось бы узнать делал кто-нить, если - да, то мож пример какой по переопределению методов, то бишь функций.. Полная аналогия с тем, что в ООП называется переопределение. smile

И даже для большего страха  smile переопределение функций не собственно-написных модулей или классов, а чего-нить из более стандартного.. Например какая-нить функция из того же DBI или CGI..

Ес-но, сама суть в том, чтобы организовать хак, при котором определенная функция переопределяется и начинает работать по иному алгоритму нежели стандартная smile

P.S. Интересует именно переопределение, а не альтернативные реализации хака ))


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
gcc
Дата 15.9.2009, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



SUPER псевдо-класс?

Код

use base qw/CGI/;        

sub header { 
my $self = shift;
unless ($myCGI::__HEADER_METHOD_WAS_RUNED_MORE_THAT_ONCE) {
  $myCGI::__HEADER_METHOD_WAS_RUNED_MORE_THAT_ONCE = 1;   # возведем ключ в пакете
  #
  # Метод супер-класса - старый header - нужно вызвать - кто-то ведь должен работать!
  # А в принципе его работа нас устраивает!
  #
  return $self->SUPER::header(@_);       # про параметры - не забываем!
  #
} else {
  
  # caller()  
  warn "Calling heaвer again... Strange situation! \n";
  

}





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


Опытный
**


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

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



делали.. для какого то мелкого модуля протокола STOMP..
Но если не используется OOP - это довольно шаткое решени.

Заменить процедуру в любом модуле легко
Код

package B;
*A::foo = sub {print "this is new foo\n";}
 

Однако, если эта процедуру кто ли-бо импортировал до момента подмены - у них останется старая. 
В этом весь трабл.
Код

package C;
use A qw(foo);

package B;
*A::foo = sub {print "this is new foo\n";}

package C;
foo(); # ooops, still old foo()


Поэтому если вы хотите такое провернуть, то нужно подменять процедуру в самом начале
Код

package B;
BEGIN {*A::foo = sub {print "this is new foo\n";}}
package C;
use A qw(foo);
foo(); #yeah! new foo is so new!



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


татарский Нео
***


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

Репутация: 5
Всего: 57



Цитата(sir_nuf_nuf @  15.9.2009,  12:51 Найти цитируемый пост)
Однако, если эта процедуру кто ли-бо импортировал до момента подмены - у них останется старая.


Вот на этом моменте я тоже призадумался

Цитата(sir_nuf_nuf @  15.9.2009,  12:51 Найти цитируемый пост)

Поэтому если вы хотите такое провернуть, то нужно подменять процедуру в самом начале


В том-то и вся проблема, что при такой реализации - все будет выглядеть еще некрасивее. smile

gcc, не натыкается-ли твой способ на эти же грабли?? smile


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
gcc
Дата 15.9.2009, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



для множественного наследования есть давно: use NEXT; http://search.cpan.org/~flora/NEXT-0.64/lib/NEXT.pm

и много разных дополнений написанных на Си  use Class::C3; http://search.cpan.org/~blblack/Catalyst-P...st/Plugin/C3.pm
http://search.cpan.org/search?query=mro&mode=all

в каталисте в новой версии используется: 
Class::C3::Adopt::NEXT http://search.cpan.org/~flora/Class-C3-Ado...3/Adopt/NEXT.pm в отладке выводиться сообщение что нужно перейти на этот модуль

(проблем с переопределение в данном случае по-моиму не будет)
Код

use Class::C3::Adopt::NEXT;

sub new {  # наследуем конструктор
    my ( $self, $c ) = @_;
        $self = $self->next::method(@_);
}



Код

  *Foo::foo = sub { (shift)->next::method(@_) };


в какой-то старой книге (Кристенсен 2 или 3 издание, я книгу сейчас не смог открыть компе) было написано что можно как-то обойти это если использовать множественное наследование с SUPER...





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


Опытный
**


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

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



Цитата(Bulat @  15.9.2009,  16:37 Найти цитируемый пост)
В том-то и вся проблема, что при такой реализации - все будет выглядеть еще некрасивее

Подменять чужие функции - вообще некрасиво.
Другое дело как это сделать менее убого..
Ну создайте отдельный модуль типа .. Startup, в котором весь этот кошмар и изложите.
А далее - либо первой строчкой своего скрипта его подгружайте, либо как startup.pl при старте mod_perl


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


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


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

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



sir_nuf_nuf, а NEXT тут разве не подходит? его автор сделал как раз для множественного наследования...
PM WWW ICQ Skype GTalk Jabber   Вверх
sir_nuf_nuf
Дата 16.9.2009, 08:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



gcc, нет. он подходит только если наследование (т.е. ООП) вообще имеет место.
Мы же говорим про импорт обычных процедур. не методов объектов


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


татарский Нео
***


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

Репутация: 5
Всего: 57



Цитата(gcc @  15.9.2009,  23:43 Найти цитируемый пост)
sir_nuf_nuf, а NEXT тут разве не подходит? его автор сделал как раз для множественного наследования... 


Действительно, это важный момент, сохранять целостность семантики кода... Тот кто после меня посмотрит мой код должен понимать не только как, но и что в нем происходит, а когда налеплено где-то процедурное, где-то ООП - это тоже не красиво... smile


Цитата(sir_nuf_nuf @  15.9.2009,  23:19 Найти цитируемый пост)
Ну создайте отдельный модуль типа .. Startup, в котором весь этот кошмар и изложите.
А далее - либо первой строчкой своего скрипта его подгружайте, либо как startup.pl при старте mod_perl 


Вариант.. smile может быть..


--------------------
менеджер по кодеврайтингу  smile 
PM MAIL WWW   Вверх
Страницы: (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.0962 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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