OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Воскресенье, 20 Октябрь, 2019 12:49

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 132 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 7  След.
Автор Сообщение
СообщениеДобавлено: Пятница, 14 Январь, 2011 15:33 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Valery Solovey писал(а):
Наверное, можно так:
...
Проверки на (message != null) перед safeLogAppend(message) не нужны, так что можно немного упростить.
Главный недостаток имхо в том, что тут появляется дублирование кода
Код:
message = TCPStreamIO.ReceiveString(POSIPStream);
safeLogAppend(message);
Это может быть чревато в будущем, при каких-то изменениях/переделках...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 15:44 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Вот такой вариант вроде бы более-менее, но всё равно смущает дублирование оператора
message = TCPStreamIO.ReceiveString(POSIPStream):
safeLogAppend(message);
Код:
            string message = TCPStreamIO.ReceiveString(POSIPStream);
            safeLogAppend(message);

            while (message != null && SrvIPStream != null && SrvIPStream.CanWrite)
            {
                TCPStreamIO.SendMsg(SrvIPStream, message + "\n");
                message = TCPStreamIO.ReceiveString(POSIPStream);
                safeLogAppend(message);
            }


Действительно ли исключение оператора break стоит всех этих усилий по его исключению? :roll:

ЗЫ. Чорд, отвлекают, аж путаюсь уже. Однозадачный я всё-таки ((


Последний раз редактировалось Geniepro Пятница, 14 Январь, 2011 16:09, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 15:55 

Зарегистрирован: Пятница, 20 Июль, 2007 17:26
Сообщения: 700
Откуда: Псков
Geniepro писал(а):
Действительно ли исключение оператора break стоит всех этих усилий по его исключению? :roll:

Рискую показаться навязчивым, но как вам безбрейковый вариант в предидущем сообщении, правда в словесах, а не в коде (не сишник я :( )


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 16:09 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Цитата:
дублирование оператора
Смотря что значит "дублирование" : ).

А сложность здесь в том, что изменения придётся синхронно вносить в разнесённые на некоторое расстояние места. Я вижу 2 типа изменений: 1) изменение источника данных 2) добавление постпроцессинга (одинакового).

Код:
message = getAndProcess(POSIPStream)


Если допускается добавление дополнительной функции, куда можно инкапсулировать эти 2 действия, то проблема отпадёт. Но появятся накладные расходы на вызов функции. А также, появится необходимость понимания назначения функции (возможно помогут говорящее название и комментарий рядом; но возможно и не помогут : ) ).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 16:15 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
albobin писал(а):
Рискую показаться навязчивым, но как вам безбрейковый вариант в предидущем сообщении, правда в словесах, а не в коде (не сишник я :( )

Не совсем понял -- нравится мне этот вариант или нет? Или как он работает?

Нравится или нет -- не могу определиться. Вроде бы достаточно прост, но дублирование кода не нравится. Хотя break тоже не особенно нравится.

А алгоритм там простой:

принимается сообщение из одного канала связи,
записывается в лог,
отправляется по другому каналу связи,
всё это повторяется, пока оба канала связи активны.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 16:19 

Зарегистрирован: Пятница, 20 Июль, 2007 17:26
Сообщения: 700
Откуда: Псков
albobin писал(а):
А , если последний не отосланный message за пределами while не нужен, то можно написать функцию с параметрами: откуда однократно прочитать, логить?, куда передать. А возвращать флаг "эндец" (нет собщения или некому отправлять) и заwhileить её


Я имел ввиду вот это сообщение


Что-то вроде этого (на си не пишу :? )

Код:
bool TransferMessage (вход, логить,выход);
{
    string message;
    bool ok ;
    message = TCPStreamIO.ReceiveString(вход);
    ok=(message != null) ;
     if (ok && логить)
       safeLogAppend(message);
     if (ok && (SrvIPStream != null) && SrvIPStream.CanWrite)
       TCPStreamIO.SendMsg(выход, message + "\n");
     else
       ok=ложь ;
     return ok
}

while ( TransferMessage(POSIPStream,правда,SrvIPStream))


Последний раз редактировалось albobin Пятница, 14 Январь, 2011 17:04, всего редактировалось 6 раз(а).

Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 16:23 

Зарегистрирован: Пятница, 24 Апрель, 2009 16:28
Сообщения: 530
Откуда: Москва
Geniepro писал(а):
Нравится или нет -- не могу определиться. Вроде бы достаточно прост, но дублирование кода не нравится. Хотя break тоже не особенно нравится.
Все эти мучения описаны Кнутом в статье "Structured Programming with go to statements", которая есть в книге "Literate Programming" viewtopic.php?p=50865#p50865


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 16:27 

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
Geniepro писал(а):
Geniepro писал(а):
32 цикла while, из них 1 с оператором break (можно переписать без break с небольшим ухудшением понятности)
Переписал вот такой код, вполне нормальный для сишника, но ужасно кривой для паскалиста:
Код:
            string message;

            while ((message = TCPStreamIO.ReceiveString(POSIPStream)) != null)
            {
                safeLogAppend(message);
                if (SrvIPStream != null && SrvIPStream.CanWrite)
                {
                    TCPStreamIO.SendMsg(SrvIPStream, message + "\n");
                }
                else
                    break; // Отправлять некому, закончим работу
            }

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 17:44 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Peter Almazov писал(а):
Все эти мучения описаны Кнутом в статье "Structured Programming with go to statements", которая есть в книге "Literate Programming" viewtopic.php?p=50865#p50865

Если попытаться переложить адский loop
Код:
loop
  …
  exit when (exit-cond)
  …
end loop
на сишный синтаксис:
Код:
loop
{
     ...
}
exit_when (exit-cond)
{
    ...
}
то получится что-то такое:
Код:
string message;

loop
{
    message = TCPStreamIO.ReceiveString(POSIPStream);
    safeLogAppend(message);
}
exit_when (message == null || SrvIPStream == null || !SrvIPStream.CanWrite)
{
    TCPStreamIO.SendMsg(SrvIPStream, message + "\n");
}


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 17:46 

Зарегистрирован: Пятница, 24 Апрель, 2009 16:28
Сообщения: 530
Откуда: Москва
И что?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 17:51 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Peter Almazov писал(а):
И что?

Ну что, что?
Жаль, что в С# нет такого оператора и возможностей его создания (путём макросов, например).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 17:55 

Зарегистрирован: Пятница, 24 Апрель, 2009 16:28
Сообщения: 530
Откуда: Москва
А чем break-то не подходит?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 17:58 

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
А зачем там на каждой итерации проверяется SrvIPStream != null ? В цикле ничто его не меняет. Разве что из другого потока кто-то что-то поменяет... С другой стороны, ничто не мешает ссылку у себя сохранить, гарантируя что ссылка всегда будет не ноль, (ведь объект этот из памяти его никто не вышвырнет пока на него есть ссылки) и проверять просто может оно писать или нет.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 17:59 
Аватара пользователя

Зарегистрирован: Воскресенье, 08 Июль, 2007 00:38
Сообщения: 778
Откуда: Москва
"exit when (exit-cond)" лучше, чем break :?:


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 18:02 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9147
Откуда: Россия, Орёл
Geniepro писал(а):
Valery Solovey писал(а):
Наверное, можно так:
...
Проверки на (message != null) перед safeLogAppend(message) не нужны, так что можно немного упростить.
Главный недостаток имхо в том, что тут появляется дублирование кода
Код:
message = TCPStreamIO.ReceiveString(POSIPStream);
safeLogAppend(message);
Это может быть чревато в будущем, при каких-то изменениях/переделках...


Евгений, при нормальном составлении циклов Вы не избежите этого дублирования, во многих случаях.
Потому что оно объективно есть. Если у Вас некоторое действие (например, попытка взятия очередного элемента при проходе по последовательности) выполняется на 1 раз больше, чем остальные действия цикла, то разумеется, что этот добавочный раз должен оказаться до (обычно) или после цикла. Противное (всякие break или лишние if) - просто хак, затуманивающий вот эту суть - действие вып. на 1 раз больше, чем сопряжённые с ним. И действие это не входит цикл, а выносится до или после него.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 18:02 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Alexey Veselovsky писал(а):
Если я не ошибаюсь, такой код лучше всего запишется на хаскеле посредством какой-нибудь монады Maybe.

В данном случае монада Maybe не покажет всю свою крутизну, для неё нужны более запущенные случаи, где куча действий может иметь недопустимый результат, и последующие действия не могут из-за этого работать.
Чем больше таких действий, тем монада Maybe выгоднее (с учётом языковой поддержки do-синтаксиса, как в Хаскелле).

Имитация этой монады на C# вряд ли что даст, наверное. Там такой жуткий синтаксический оверхед будет... :lol:


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 18:04 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Peter Almazov писал(а):
А чем break-то не подходит?

Тем, что break нелюбим оберонщиками. Да в оберонах и нет никакого break...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 18:07 

Зарегистрирован: Вторник, 25 Апрель, 2006 16:21
Сообщения: 2180
Откуда: Нижний Новгород
Geniepro писал(а):
Peter Almazov писал(а):
А чем break-то не подходит?

Тем, что break нелюбим оберонщиками. Да в оберонах и нет никакого break...

Но есть RETURN и вложенные функции!
Правда в Oberon-07 RETURN'a уже нет... Как и массивов неизвестной на этапе компиляции длины.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 18:07 

Зарегистрирован: Четверг, 12 Июль, 2007 23:18
Сообщения: 1982
Откуда: Узбекистан, Чирчик
Alexey Veselovsky писал(а):
А зачем там на каждой итерации проверяется SrvIPStream != null ? В цикле ничто его не меняет. Разве что из другого потока кто-то что-то поменяет... С другой стороны, ничто не мешает ссылку у себя сохранить, гарантируя что ссылка всегда будет не ноль, (ведь объект этот из памяти его никто не вышвырнет пока на него есть ссылки) и проверять просто может оно писать или нет.

Нет гарантии, что SrvIPStream не будет уничтожен в других процессах...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 14 Январь, 2011 18:11 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9147
Откуда: Россия, Орёл
break, во-первых, нарушает "инкапсуляцию управления" (внутреннее содержание конструкции может влиять на её завершение) - это противоречит привычному стилю изучения программы "снаружи вглубь".
Во-вторых, break даёт программисту свободу и "искушение" писать "оригинальные" циклы, непохожие друг на друга, вместо того, чтобы разглядеть в задаче цикла её основную природу и организовать цикл какой-либо типичной структуры.
Если природа "не разглядывается", то надо абстрагироваться - скрыть какие-то технические детали за процедурами-типами.

Был пример на Компьютерре, одному участнику переписали код таким образом. Код был на С++.
См. вот это сообщение: http://www.computerra.ru/forum/index.ph ... age1136258
- задача,
и следующее за ним - её переделка.
(там одна опечатка есть, а именно - p переобъявлено внутри цикла...)


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 132 ]  На страницу Пред.  1, 2, 3, 4, 5 ... 7  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB