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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Стандартизированый модульный интерфейс, установка и работа модулей 
:(
    Опции темы
DiverD
Дата 4.3.2007, 02:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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




Попробую описать свой вопрос, нужна написать стандартизированый модульный интерфейс , на основе которога писались бы модули. Т.e. у нас есть general.pl который подгружает модули из lib "mods" при этом не нужна править сам general.pl в зависимости от работы модуля, иными словами можна взять за пример скажем 3d studio max, т.е. у нас установлен дистриб, вот скачали мы плагин который улучшает наложение шейдеров, заинсталили его, запустив 3d max плагин этот уже в деле.

ps: даже не знаю с чего начать, но идея дика заинтересовала.
--------------------
[ FreeBSD & pERL p0WER eVERY dAY ]
PM MAIL   Вверх
tishaishii
Дата 4.3.2007, 04:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Какой-то сумбур в вопросе.
Не так часто и быстро. Объясни подробнее.
PM MAIL ICQ Skype   Вверх
DiverD
Дата 4.3.2007, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Ну вот пару ссылок нашел:
http://en.wikipedia.org/wiki/Abstract_factory_pattern
http://www.rsdn.ru/article/patterns/AbstractFactory.xml
ну вот что та нашел...
--------------------
[ FreeBSD & pERL p0WER eVERY dAY ]
PM MAIL   Вверх
nitr
Дата 4.3.2007, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



DiverD, поиск на форуме неплохой, недавно работу с плагинами обсуждали


--------------------
PM   Вверх
shamber
Дата 4.3.2007, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



DiverDсмотри тут, правда до совсем готового решения там далеко smile, Но если чего наделаешь пиши. smile
PM MAIL Jabber   Вверх
Zuzu
Дата 7.3.2007, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код


#!/usr/bin/perl -w
#
# Основной управляющий скрипт режима администрирования
#

use lib "$ENV{DOCUMENT_ROOT}/../mod";
#
use strict;
#
# загрузим необходимые модули
use CGI;
#use CGI::Carp;
#

my $cgi = new CGI;

my $module = $cgi->param('module') || 'auth';
my $method = $cgi->param('method') || 'start';

my ($obj, $is_ok, $proc);

my $default_module = "auth";
my $default_method = "start";

$module =~ s/\s//g;
$method =~ s/\s//g;

warn "index.cgi GET: Method: $method, Module: $module \n";
#

if (not execute($module, $method, $cgi)) {
  #
  # напишем, что возникла проблема и загрузим модуль по умолчанию
  #
  warn "Illegal call or error. method: $method, module: $module";
  unless (execute($default_module, $default_method, $cgi)) {
    print $cgi->header();     # совсем все плохо...
    print "All Bad!";
  }
}

exit;


# ------------------------------------------------------------------------------


sub execute {
#
# выполнение метода из модуля
#

my ($module, $method, $cgi) = @_;
my $obj;
#
#warn "Method: $method, module: $module \n";
#
if ($method =~ /^_/) {       # "закрытые" методы (что начинаются с _) не вызываем !
  warn "Can't EXECUTE internal method: $method at module: $module. \n";
  return 0;
}
#
eval("use $module");
if ($@) {
  warn "Can't USE module: $module. Error: $@ \n";
  return 0;
}

eval('$obj = new ${module} $cgi');
if ($@) {
  warn "Can't run 'new' in module: $module. Error: $@ \n";
  return 0;
}

unless ($obj->can($method)) {
  warn "Can't found method: $method in module: $module.\n";
  return 0;
}

$obj->${method}();
return 1;
#
# Done ! (execute)
#
}

# ------------------------------------------------------------------------------      


Такого счастья хочешь или тебе нужна реальная Абстрактная Фабрика smile

Скрипт написан около трех лет назад (с тех пор я про него просто забыл -  он просто работает smile ), поэтому комментарии приветствуются.



--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
tishaishii
Дата 8.3.2007, 08:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Я бы лучше:
Код
use lib "$ENV{DOCUMENT_ROOT}/../mod";#по-моему, Perl так не умеет
use strict;
use CGI;

my$cgi=CGI->new;
my$module=$cgi->param('module') || 'auth';
my$method=$cgi->param('method') || 'start';
my($obj, $is_ok, $proc);
my$default_module='auth';
my$default_method='start';
$module=~s/\s//go;
$method=~s/\s//go;
warn "index.cgi GET: Method: $method, Module: $module\n";

unless(&execute($module, $method, $cgi)) {
  warn "Illegal call or error. method: $method, module: $module\n";
  unless(&execute($default_module, $default_method, $cgi)) {
    print $cgi->header; # совсем все плохо...
    print 'All is bad!';
  }
}
exit;
# ------------------------------------------------------------------------------
sub execute {
    my($module, $method, $cgi)=(shift, shift, shift);
    unless(index $method, '_') {
        warn "Can't EXECUTE internal method: $method at module: $module. \n";
        return undef
    }
    eval 'use '.$module;
    if ($@) {
        warn "Can't USE module: $module. Error: $@\n";
        return undef
    }
    unless(&UNIVERSAL::can($module, 'new')) {
        warn "Can't run 'new' in module: $module. Error: $@\n";
        return undef
    }
#    unless ($obj->can($method)) { $obj->can - не определён изначально, читай толстую умную книжку.
    unless (&UNIVERSAL::can($module, $method)) {
        warn "Can't found method: $method in module: $module.\n";
        return undef
    }
    $module->new($cgi)->$method;
    +1
}


Добавлено @ 08:32 
Или, тогда уж, *main::can=*UNIVERSAL::can;

Это сообщение отредактировал(а) tishaishii - 8.3.2007, 08:29
PM MAIL ICQ Skype   Вверх
DiverD
Дата 9.3.2007, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



thnx, попробую потом отпишу
--------------------
[ FreeBSD & pERL p0WER eVERY dAY ]
PM MAIL   Вверх
Zuzu
Дата 9.3.2007, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



DiverD, не заморачивайся Абстрактной Фабрикой! Web-оно в 99% случаев требует более простых (более легких и более быстрых в реализации) решений.

Если хочешь посмотреть что "полегче" - начни отсюда:
http://ooad.asf.ru/Patterns_title.aspx?IdKat=9
Все эти решения,  в какой-то мере, наверно каждый у себя использовал. 

P.S. Если ты знаком с Шаблонами Проектирования, эта ссылка покажется тебе очень легким чтивом. Тогда уж, извини.


--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
Zuzu
Дата 9.3.2007, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



tishaishii,  спасибо за  комментарии.

Видимо реально настало время провести Refactoring (улучшение кода) для моего, уже давно работающего, программного обеспечения. smile

Про use lib.

Не особо много хостинговых серверов я знаю, но на всех из мне известных есть правильно возведенная $ENV{DOCUMENT_ROOT} и оно работает. И под Perl 5.6 и под 5.8. Естественно, предпологается, что index.cgi запускается из-под web-сервера, поэтому наличие/отсутсвие $ENV{DOCUMENT_ROOT} просто не проверяется. Да и использовать FindBin не было особого желания.

По твоему коду есть два мелких комментария. 

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

2. $module->new($cgi)->$method;

У sub execute() есть еще одна особенность. Она не должна  выдавать ошибок, которые к ней, к execute, не относятся. Т.е. если есть ошибка в модуле или его вызвали неверно, сказать об этом разработчику и указать, по возможности, не на себя, а на тот модуль, который эту ошибку вызвал.

Во-первых, у тебя нет проверки на "объекность" модуля (у меня ее тоже не было, кстати), поэтому эта строка может вызвать ошибку времени выполнения (прямо в этой строке, в sub execute {} ), хотя реально "ответсвинен за ошибку" тот модуль, который мы вызывали (пытаемся вызвать).

Во-вторых, ИМХО, такая реализация менее читаема.

Если ты подразумевал такой строчкой реализацию механизма распределенного управления (distributed control) (вместо централизованного управления - см. М. Фаулер, UML-2, основы, главу 4, про диаграммы последовательностей), то такая реализация к нему не приводит. Все равно сначала вычисляется new(), ссылка на объект возвращается в execute() и оттуда снова выполняется $method.

Постарался учесть это все в коде, который привожу ниже (только sub execute). Несмотря на то, что сразу поставил на рабочий проект, отладить по-нормальному просто не было времени.

Код

sub execute {
#
my ($module, $method, $cgi) = (shift, shift, shift);
my $anObj;
#
# "закрытые" методы (сам new() и что начинаются с _) не вызываем!
if (index($method, '_') == 0 or $method eq 'new') {       
  warn "Can't EXECUTE private method: '$method' in module: '$module'.\n";
  return 0;
}
#
# попробуем USE...
eval 'use ' . $module; 
if ($@) {
  warn "Can't USE module: '$module'. Error: $@ \n";
  return 0;
}
#
# попробуем NEW...
# придется перехватить, хотя может слегка затруднить отладку new()
eval { $anObj = new $module ($cgi); };
if ($@) {
  warn "Can't run 'new' in module: '$module'. Error: $@ \n";
  return 0;
}
#
# Модуль должен быть объектно-ориентированным! Так надо!
unless (ref($anObj) and index($anObj, '=') > 0) {
  warn "Module '$module' must be an OBJECT-ORIENTED! \n";
  return 0;
}
#
# А есть ли метод?
unless ($anObj->can($method)) {
  warn "Can't found method: '$method' in module: '$module'.\n";
  return 0;
}
#
# Ничего не перехватываем. Если есть ошибки выполнения - 
# пусть об этом нам сообщит сам модуль!
$anObj->${method}();
#
# Done! (execute)
#
return 1;
}


--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
tishaishii
Дата 9.3.2007, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Ой, не знаю про что ты написал. Там куча каких-то умных формулировок.
Но я однозначно против eval всуе: eval { $anObj = new $module ($cgi); };
И так и не понял, откуда берётся метод can у любого модуля. Ну нет у него такого метода по-умолчанию.
PM MAIL ICQ Skype   Вверх
DiverD
Дата 10.3.2007, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Zuzu не я не для веба пишу, решил написать бота работающего по средсвам irc, что бы к ниму можна было писать плагины ( модули ) в определенном стандарте, что бы скажем кидал эти модули в папку plugins и при старте бота они автоматом подгружались и можны было с ними работать..

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

ps: по идеи не сложна, в голове что та крутиться но выдать не могу=))
--------------------
[ FreeBSD & pERL p0WER eVERY dAY ]
PM MAIL   Вверх
shamber
Дата 10.3.2007, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



DiverD, не парься для IRC есть такая тема с поддержкой плагинов POE::COMPONENT::IRC
PM MAIL Jabber   Вверх
DiverD
Дата 11.3.2007, 00:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



я знаю про POE и другой CPAN но мне не нужны модули=)

--------------------
[ FreeBSD & pERL p0WER eVERY dAY ]
PM MAIL   Вверх
Zuzu
Дата 11.3.2007, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Забудем про парадигмы управления (описанные, в частности, М.Фаулером). Оно нам на самом деле здесь ни к чему. Извини, на самом деле слегка скатился во флэйм. Просто я, когда "игрался" с реализациями (на Perl) механизмов  распределенного управления, допустил аналогичную ошибку. Вот и понесло...

Цитата(tishaishii @  9.3.2007,  21:03 Найти цитируемый пост)
И так и не понял, откуда берётся метод can у любого модуля. Ну нет у него такого метода по-умолчанию


Все модули, которые находятся в каталоге mod - объектно-ориентированные. По сути, это классы. Или, в терминах Perl, процедура new()  каждого пакета (package) возвращает ссылку, приведенную (blessed) к этому пакету. Я думаю, очевидно, что в этом случае порожденный объект будет иметь (по крайней мере) еще и методы "родительского" класса UNIVERSAL, который является родительским классом по-умолчанию (perldoc perltoot, UNIVERSAL: The Root of All Objects). Поэтому вызов метода can() корректен для любого объекта. 

Если не секрет, почему тебя смущает eval {} ? Были какие-то случаи? Я всегда считал eval - этаким механизмом перехвата ошибок. Об этом, в частности, написано в документации. (perldoc -f eval)

Меня в твоем коде больше смущает вызов функции, как процедуры пакета ( &UNIVERSAL::can($module, 'new')) ), для проверки наличия new() как метода создаваемого объекта. Т.е. проверяется именно наличие процедуры new() в пакете $module. При этом:

Во-превых,  происходит (может у меня в голове?) некое торможение из-за одновременного использования двух различных стилей (процедурного и объектно-ориентированного) для, по идее, одной сущности - нашего вызываемого метода из нашего объекта. Как говорится, либо объекты, либо процедуры. Лично я стараюсь без особой необходимости не мешать их друг с другом.

Во-вторых, про объектно-ориентированную суть $module мы так ничего и не узнаем.

Добавлено @ 11:32 
Цитата(DiverD @  10.3.2007,  18:06 Найти цитируемый пост)
Посморел ваши реализации немнгога доганяю но не до конца


Все достаточно просто. 

1. Есть каталоги

mod - для модулей
www  - для кортя сервера

2. В каталог mod помещаются файлы, названные одноименно с именем пакета (класса)

Код

order.pm
------------
...
package order;
...
sub new{
...
}

sub show {  # выводит форму
...
}

sub save {  # вызывается для записи информации
...
}
----------------


3. В каталог www помещается файл-контроллер (index.cgi)

4. Вызов нужного модуля происходит при "нажатии" на ссылку типа:

index.cgi?module=order&method=show

5. Желающие могут "завернуть URL" с помощью .htaccess (чтобы спрятать внутренний механизм реализации, например)

6. Чтобы предотвратить вызов (контроллером) "неправильных" методов из "неправильных" объектов, они распологаются либо не в каталоге mod, либо имя файла не совпадает с именем пакета. smile





Это сообщение отредактировал(а) Zuzu - 11.3.2007, 14:24
--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
DiverD
Дата 12.3.2007, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



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


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

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


 




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


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

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