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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как бы вы задизайнили API, Вопрос к гуру 
:(
    Опции темы
Danissimo
Дата 13.12.2006, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Я попытался сделать сам. Мало чего хорошего получилось. Мой вопрос к гуру следующий: как бы вы решили следующую задачу.

Вы достаете строчки из БД. Для БД значение null -- нормальная ситуация. Значение null в перле представлены значением undef. Хочется вести лог. Причем, если написать

print "Result: $result\n";

то рикуем получить ошибку, типа значение $result не определено. Чтобы не получать этого сообщения и в то же самое время видеть в логе, что значение не определено, можно объявить подпрограмму definize, и вызывать вот таким образом:

print 'Result: ' . definize $result . "\n";

Также видится, что можно определить базовый класс для операций с БД. Он будет хранить как минимум connection с БД. В то же время для удобства, наверное, в нем можно определить операции для логирования. Скажем debug(), info(), error() и т. д.

Как бы вы задизайнили и запрограммировали бы подобную задачу.

Я вот пытаюсь натянуть имеющийся у меня богатый опыт из других языков. Может я зря пытаюсь это сделать. Поэтому я и обращаюсь к вам, гуру, за советом. У вас ведь больше опыта, вы знаете, как лучше?
PM MAIL   Вверх
nitr
Дата 13.12.2006, 19:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



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

my $result;
$result = результ из запроса к БД

либо это я так делаю ;) что не бывает ошибки...

Добавлено @ 19:28 
даже как тест smile
Код

#!perl -w
use strict;
my $result;
$result = undef;
defined $result ? print "Result: $result\n" : print "Result: null\n";

Цитата

D:\>1.pl
Result: null


Это сообщение отредактировал(а) nitr - 13.12.2006, 19:27


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


Бывалый
*


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

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



Во-во, я вот как раз об это и говорю. Чтобы не писать таких вот строк:

defined $result ? print "Result: $result\n" : print "Result: null\n";

предлагается использовать вспомогательную подпрограмму, которую можно использовать вот так:

print "Selected: <$id" . definize $when . ', ' . definize $ref . ', ' . definize $terminated . ">\n";

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

defined ???...

можно. Но не нужно.

Добавлено @ 20:22 
Или даже еще проще:

print 'Selected: <' . join(', ', definize($when, $ref, $terminated)) . ">\n";

 smile  Для програмки, написанной на коленке, к которой предъявляются такие же требования надежности, можно и defined ? print : print написать =))) Но на этом область применения и заканчивается.

Это сообщение отредактировал(а) Danissimo - 13.12.2006, 20:23
PM MAIL   Вверх
korob2001
Дата 14.12.2006, 05:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

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



Цитата(Danissimo @  13.12.2006,  17:19 Найти цитируемый пост)
Во-во, я вот как раз об это и говорю. Чтобы не писать таких вот строк:

Напиши один раз такую подпрограмму и прогоняй через неё данные полученные из базы, как через фильтр:
Код

sub filter {
       my $res = shift;
       return defined $res ? $res : "NULL";
}

##### my $result = filter(результ из запроса к БД);
print filter(undef) . "\n";
print filter(50) . "\n";
print filter("Строка") . "\n";

Можно так же заюзать значения по умолчанию, например так:
Код

my $result = результ из запроса к БД || "";

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


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Danissimo
Дата 14.12.2006, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Короб, ты гений. Действительно, можно ведь просто, передать весь прочитанный массив в подпрограмму, которая умеет обрабатывать массивы. Это хороший шаг вперед.

Однако остался открытым вопрос. Преамбула:
Код

package DAO;
sub definize {
    # Обратите внимание, это просто подпрограмма. то не метод класса DAO.
    # И именно как подпрограмму ее и хочется использовать.
    return map { defined $_ ? $_ : 'NULL' } @_;
}

sub new {
    # А это уже конструктор
    my $class = shift;
    my $conn = shift || Carp::croak('$conn=null');
    return bless { 'CONN' => $conn }, $class;
}

sub _getConn {
    my $self = shift;
    return $self->{'CONN'};
}

package MyDAO; # Это наследник DAO
use base 'DAO';

sub getData { # Это метод класса MyDAO
    my $self = shift;
    my $sql = shift || Carp::croak('$sql=null');
    my $stmt = $self->_getConn()->prepare($sql);
    $stmt->execute;
    my($col1, $col2, $col3) = $stmt->fetchrow_array;
    print 'Selected: <' . definize($col1, $col2, $col3) . ">\n"; # Вот из-за этой строчки "война"
    # Я думаю, удобно вызывать definize для логирования. Только не понятно, каким образом
    # объяснить перлу, что я вызываю не меотд класса, а просто подпрограмму, и не надо
    # пытать интерпретировать первый аргумент, как ссылку на объект класса.
    return ($col1, $col2, $col3);
}

Собственно, вопрос -- как вызывать definize с как можно меньшим кол-вом писанины.
PM MAIL   Вверх
Nab
Дата 14.12.2006, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ну уже ж написали, что эту функцию нужно експортировать...
Не хочешь юзать Exporter, експортируй сам, но имхо это лишнее...


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
Danissimo
Дата 15.12.2006, 09:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(Nab @ 14.12.2006,  20:29)
Ну уже ж написали, что эту функцию нужно експортировать...
Не хочешь юзать Exporter, експортируй сам, но имхо это лишнее...

Э-эхх, не хватает мне опыта. Смотрю на конструкции, как баран на новые ворота.

В конце концов с вашей помощью сделал маленький примерчик. Вроде, заработало. Практической пользы -- никакой. Зато вот такое наблюдение:

ClassA.pm
Код

package ClassA;

use strict;
use warnings;
use diagnostics;

require Exporter;
our @ISA = ('Exporter');
our @EXPORT = ('definize');

sub definize {
    return map { defined $_ ? $_ : 'null' } @_;
}

sub new {
    return bless {}, shift;
}

sub render {
    my $self = shift;
    print +(shift) . "\n";
}

1;


ClassB.pm
Код

package ClassB;

use strict;
use warnings;
use diagnostics;

use ClassA;
our @ISA = ('ClassA');

sub cough {
    my $self = shift;
    $self->render(ref($self) . ' - ' . join(', ', definize(@_)));
}

1;


testAB.pl
Код

use strict;
use warnings;
use diagnostics;

use ClassB;

my $obj = new ClassB();
$obj->cough(1, 2, 3);


Запускаем, все отлично:
Код

ClassB - 1, 2, 3


Теперь делаем простейший трюк: заменяем все ClassA на просто A, ClassB -- на B. Вот результат:
Код

Can't locate object method "new" via package "B" at AB.pl line 7 (#1)
    (F) You called a method correctly, and it correctly indicated a package
    functioning as a class, but that package doesn't define that particular
    method, nor does any of its base classes.  See perlobj.

Uncaught exception from user code:
        Can't locate object method "new" via package "B" at AB.pl line 7.
 at AB.pl line 7


У меня объяснений нету. Одни буквы smile
PM MAIL   Вверх
korob2001
Дата 17.12.2006, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

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



Цитата(Danissimo @  15.12.2006,  06:34 Найти цитируемый пост)
Теперь делаем простейший трюк: заменяем все ClassA на просто A, ClassB -- на B. Вот результат

Вот этой части не понял, поясни подробнее. Что значит заменяем ClassA на просто А?



--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
Zuzu
Дата 18.12.2006, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(Danissimo @  14.12.2006,  18:56 Найти цитируемый пост)
 ... 


Код


print 'Selected: <' . definize($col1, $col2, $col3) . ">\n"; # Вот из-за этой строчки "война"
    # Я думаю, удобно вызывать definize для логирования. Только не понятно, каким образом
    # объяснить перлу, что я вызываю не меотд класса, а просто подпрограмму, и не надо
    # пытать интерпретировать первый аргумент, как ссылку на объект класса.


Другой вариант. Просто проигноритуй первый переданный аргумент (просто напиши shift). Только лично мне нравится вызов "без $self-> ". Всегда пишу $self-> ...  перед методом. Чтобы проблемы в дальнейшем не отгребать. 

Хочешь еще уменьшить код - помести print внутрь процедуры. =)


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


Бывалый
*


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

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



Цитата(korob2001 @ 17.12.2006,  15:36)
Цитата(Danissimo @  15.12.2006,  06:34 Найти цитируемый пост)
Теперь делаем простейший трюк: заменяем все ClassA на просто A, ClassB -- на B. Вот результат

Вот этой части не понял, поясни подробнее. Что значит заменяем ClassA на просто А?

Я имел в виду переименовать файл ClassA.pm в A.pm, а также все упоминания класса ClassA в коде заменить на A.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


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

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


 




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


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

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