Re: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 07.07.05 02:20
Оценка: 118 (11) -1
Патрик,

> Что уважаемая общественность думает о необходимости документировать/комментировать код?

> Я смотрю, что мнения на этот счёт радикально расходятся

По крайней мере, легко согласиться с тем, что нужно документировать неочевидные моменты. Конечно, критерии очевидности очень сильно сильно зависят от человека к человеку, но если сойтись на буквальной трактовке слова "очевидный", то станет несколько легче. А именно: если некоторое предположение, сделанное автором, или причина, почему именно так написано, не видны из кода, то нужно их задокументировать. С другой стороны, возможно, стоит подумать о том, как сделать видимыми в коде вещи, размещаемые в комментариях...

Например, из свеженького.

Есть интерфейсы — наследники некоторого ICommunicator, представляющие собой связь некоторых backend операций с окружением, в том числе с GUI. Например, если в ходе выполнения операции обнаружилось, что некоторый файл копируется поверх уже существующего, то backend операция "спрашивает", что нужно делать: заменить файл, пропустить его, оставив уже существующий, или вообще прервать всю операцию. Или, скажем, каталог назначения не существует, и нужно получить подтверждение. Изначально в качестве результатов подобных функций были выбраны символы, представляющие собой акроним названия кнопки, выбранной пользователем в соответствующем диалоге. Скажем 'o' — "OK", 'r' — "Retry", 'v' — "Overwrite", 'c' — "Cancel", 'k' — "Skip" и т.п.
struct ICommunicator
{
  virtual char file_exists( Path const& ) = 0;
  virtual char destination_folder_does_not_exists( Path const& ) = 0;
  . . .
};

Использование:
. . .
if ( file_exists( path ) )
{
  switch ( communicator.file_exists( path ) )
  {
  case 'c':
    . . .
    break;

  case 'v':
    . . .
    break;

  case 'k':
    . . .
    break;

  default:
    throw UnexpectedCommunicatorAnswer();
  }
}
. . .

. . .
if ( !file_exists( path ) )
{
  switch ( communicator.destination_folder_does_not_exists( path ) )
  {
  case 'c':
    . . .
    break;

  case 'o':
    . . .
    break;

  default:
    throw UnexpectedCommunicatorAnswer();
  }
}
. . .

Сразу бросается в глаза, что в точке использования сложно вспомнить, что какой символ обозначает. Можно это дело задокументировать:
. . .
if ( file_exists( path ) )
{
  switch ( communicator.file_exists( path ) )
  {
  case 'c': // Cancel
    . . .
  case 'v': // Overwrite
    . . .
  case 'k': // Skip
    . . .
  default:
    throw UnexpectedCommunicatorAnswer();
  }
}
. . .

А иногда, даже зная, что, скажем, символ 'o' означает "OK", все равно неясно, что именно означает "OK" в данном случае.
. . .
if ( !file_exists( path ) )
{
  switch ( communicator.destination_folder_does_not_exists( path ) )
  {
  case 'c': // Cancel
    . . .
  case 'o': // here "OK" means that we should go on and create missing folder
    . . .
  default:
    throw UnexpectedCommunicatorAnswer();
  }
}
. . .

Также нужно документировать интерфейс, чтобы описать, что же за char возвращают данные функции...


Вместо узаконивания такого положения дел комментированием можно сделать два очевидных шага: 1) уйти от акронимов названий кнопок, вообще абстрагируясь от конкретных вариантов, предложенных пользователю; 2) ввести константы с понятными именами, чтобы не надо было в точке использования документировать все это дело. Скажем, ввести перечислимый тип, включающий все возможные варианты "смыслов" ответов пользователя:
enum CommunicatorAnswer
{
  communicator_cancel,
  communicator_continue,  // go on, ignore the warning and continue the operation
  communicator_overwrite,
  communicator_skip,
  communicator_retry
};

Стало немного понятнее:
struct ICommunicator
{
  virtual CommunicatorAnswer file_exists( Path const& ) = 0;
  virtual CommunicatorAnswer destination_folder_does_not_exists( Path const& ) = 0;
  . . .
};

if ( file_exists( path ) )
{
  switch ( communicator.file_exists( path ) )
  {
  case communicator_cancel:    . . .
  case communicator_overwrite: . . .
  case communicator_skip:      . . .
  default:                     throw UnexpectedCommunicatorAnswer();
  }
}

if ( !file_exists( path ) )
{
  switch ( communicator.destination_folder_does_not_exists( path ) )
  {
  case communicator_cancel:    . . .
  case communicator_continue:  . . .
  default:                     throw UnexpectedCommunicatorAnswer();
  }
}

Однако теперь видны другие недостатки: 1) в месте объявления функций-членов ICommunicator совершенно неочевидно, какие из вариантов ответов они могут возвращать; 2) в точке использования неясно, учтены ли все варианты ответов, или же по ошибке о каком-то из них забыли.

Можно разбавить код комментариями...


А можно так изменить код, чтобы было совершенно очевидно, какие варианты ответов может возвращать та или иная функция, и чтоб в месте использования можно было легко увидеть, что никакой из возможных вариантов не забыт:
struct ICommunicator
{
  virtual CommunicatorAnswer<
            communicator_cancel |
            communicator_overwrite |
            communicator_skip >        file_exists( Path const& ) = 0;

  virtual CommunicatorAnswer<
            communicator_cansel |
            communicator_continue >    destination_folder_does_not_exists( Path const& ) = 0;
  . . .
};

if ( file_exists( path ) )
{
  CommunicatorAnswer<
      communicator_cancel |
      communicator_overwrite |
      communicator_skip >        answer = communicator.file_exists( path );

  if ( answer == communicator_cancel )
    . . .
  else if ( answer == communicator_overwrite )
    . . .
  else if ( answer == communicator_skip )
    . . .
}

if ( !file_exists( path ) )
{
  CommunicatorAnswer<
      communicator_cansel |
      communicator_continue >    answer = communicator.destination_folder_does_not_exists( path );

  if ( answer == communicator_cancel )
    . . .
  else if ( answer == communicator_continue ) // create the folder
    . . .
}

Более того, как можно заметить, мы еще и избавились от проверки времени исполнения, что получен ожидаемый ответ, т.к. теперь это делается во время компиляции! Заодно сравнить результат функции с ответом, который она не может вернуть, нельзя — это также будет диагностировано компилятором.

Как видно, один комментарий в коде, все-таки, остался... Но надо же, в конце концов, на чем-то остановиться!
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Нужно ли документировать код?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.07.05 09:18
Оценка: 3 (2) +6
Здравствуйте, Патрик, Вы писали:

П>Сам я придерживаюсь мнения о том, что во многом наличие/отсутствие документации зависит от культуры организации. В некоторых организациях знания хранятся в головах у сотрудников, в некоторых — в документах ворда. И я лично, плохого в этом не виду ничего.


П>Например наш проект, средний по размеру (~40 человеко/лет) пережил уже несколько версий, частично сменилась команда которая над ним работает и при всё при этом документации по нему по сути нет никакой, ни по архитектуре, ни по коду. Комментариев в коде нет тоже. И проблем это не вызывает. Обратите внимание, я не говорю что это круто — я лишь говорю, что нам это не доставляет никаких проблем. А если нет разницы — зачем платить больше? (с)


Ну если нет разницы, то действительно, зачем платить больше?
Пока гром не гремит, зачем креститься-то?

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

Да и сейчас мной написано столько всего, что я просто не в состоянии помнить форматы каких-нибудь методов и их особенности. В таких случаях автодокументаторы типа doxygen или javadoc очень выручают. Загружаешь в браузере доку по библиотеке и видишь не только форматы и пояснения, но и примеры можно посмотреть и даже туториалы. А в продвинутых IDE тебе тоже самое прямо по ходу набора текста подсказывается. Я считаю, что за такое удобство можно заплатить временем на написание комментариев в коде.




Сам я придерживаюсь мнения, что код документировать нужно обязательно. Даже если он и кажется тривиальным. Имхо, это как противопожарная безопасность: лучше перебдеть, чем перебзд... Поэтому, если в ходе code review я вижу незадокументированный код, то даю по рукам и заставляю задокументировать его.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Нужно ли документировать код?
От: korzhik Россия  
Дата: 06.07.05 09:52
Оценка: +3 :)))
Здравствуйте, Патрик, Вы писали:

П>Что уважаемая общественность думает о необходимости документировать/комментировать код?


Комментировать конечно надо, только с умом: пришлось помню разбираться в старом коде на работе. Там было очень мало комментариев, а те которые были являлись бесполезными... ну например, как мило после кропотливого анализа пары экранов кода без комментариев встретить такой коментарий:
  int step; // шаг

очень умиляет
Re: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 06.07.05 11:28
Оценка: 1 (1) +4
Здравствуйте, Патрик, Вы писали:

П>Что уважаемая общественность думает о необходимости документировать/комментировать код?


Думаю, что по возможности код должен обладать следующими характеристиками:
1. Понятность, т.е. его должно понимать максимальное количество программистов.
2. Легкость модификации, т.е. если код потребуется изменить через большой промежуток времени и возможно не тому кто его создал, то это не должно вызвать затруднений (в том числе и с пониманикм).
3. Осмысленность, т.е. код должен делать то, что планировал его создатель.

Так вот комментарии помогают достичь всех этих целей. Конечно если они сделаны с умом и если нет других факторо на прочь убивающих толк от комментариев.

Так что коментарии не самоцель, а одна из састовляющих при получении качественного программного продукта.
... << RSDN@Home 1.2.0 alpha rev. 516>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Нужно ли документировать код?
От: Кодт Россия  
Дата: 07.07.05 11:32
Оценка: 2 (1) +1
Здравствуйте, eao197, Вы писали:

E>>>А во что это все превратиться, если потребуется новые коды возврата добавить? timedout, например?


К>>В пересмотр всей программы. Если изменился контракт объекта (он стал возвращать новые значения), то есть смысл во всех точках вызова убедиться, что эти новые значения корректно обработаны. Здесь компилятор просто заставит это сделать


E>Да это-то я понимаю. Мне просто интересно, хорошо ли это? Нет ли здесь попытки замутить сознание в тривиальном, в общем-то, случае?


Ничего себе тривиальный.

В проекте, который мы сейчас делаем, дофига COM-объектов — так исторически сложилось. Естественно, что методы интерфейсов писались "по-честному", то есть возвращали HRESULT.
На самом деле, в большинстве случаев это было S_OK, либо S_OK + несколько типичных кодов ошибки (S_FALSE, E_FAIL, изредка E_NOINTERFACE, E_NOTIMPL) и отлупы на пред- и пост-условиях (E_INVALIDARG, E_POINTER, E_OUTOFMEMORY, E_UNEXPECTED).
Приходилось помнить, что ожидать от какого метода. То есть проверять hr==S_OK, hr==S_FALSE, hr==E_FAIL и не забывать, что он может вернуть что-то неожиданное.
В случае неожиданного ответа значение чаще всего либо возвращалось, либо игнорировалось. В результате контракт каждого метода звучал так: "возвращаю S_OK и E_FAIL осмысленно, а всё остальное и иногда E_FAIL — если меня самого удивят".

В конце концов мне надоело, и я переделал некоторые интерфейсы вдребезги пополам. Благо, что COM-объекты внутренние.
1) все нарушения пред- и пост-условий — в ассерты.
2) все неожиданности — в исключения.
3) тип возврата точно соответствует контракту
— S_OK -> void
— S_OK,S_FALSE -> BoolType (не bool и не enum, чтобы не было неявных приведений к HRESULT)
— S_OK,E_FAIL -> OkFailType (опять же, ничего неявного)
После этого я плакаль: выловил тучу бессмысленных проверок и ещё тучу забытых проверок...
Перекуём баги на фичи!
Re[7]: Нужно ли документировать код?
От: Кодт Россия  
Дата: 07.07.05 13:36
Оценка: 1 (1) +1
Здравствуйте, eao197, Вы писали:

E>Вообще-то я говорил именно про пример с "Нефиг, Нафиг, Пофиг" (т.е. Abort/Retry/Ignore). Имеет ли смысл наворачивать нетривиальные конструкции на шаблонах для таких тривиальных случаев? Будет ли это упрощение или, наоборот, усложнение кода? В конкретно том примере, который привел Павел, мне показалось, что применение шаблонов -- это overkill.


Не оверкилл (и даже не оверхед).
Есть несколько стандартных комбинаций (Ok, Ok/Cancel, Yes/No/Cancel...), всего около десяти-двадцати разных сочетаний.
Принципы их обслуживания (и во время компиляции, и во время исполнения) — одинаковые. Не такие уж сложные, но и не настолько прозрачные, чтобы копипастить повсеместно.
Естественно, мы выносим общую часть в библиотеку; а поскольку нам нужно ещё и компилятор озаботить — проверкой типов, статическими ассертами и т.д. — это будет библиотека шаблонов.
Сделали и успокоились. Теперь берём наши стандартные комбинации и привязываем их к шаблонам — наследование, typedef, как угодно.

E>Ты же приводишь пример с COM, который явно в другой весовой категории.


Совершенно та же весовая категория. В моём случае, не применительно к COM вообще.
Главная заруба была именно в количестве исходников, которые нужно было рефакторить. Поэтому метод "вдребезги пополам" (когда компилятор начинает ругаться на каждом углу) себя оправдал.

E>Я в таких случаях иногда делал функции check_<some_lib> и пропускал все вызовы через них. А там проверял код возврата и генерировал исключения.

E>И вот в таких случаях подход Павла мне показался интересным. Только вот что делать, если коды возврата нельзя по битовой маске объединять, т.к. они являются простыми перечислениями? Как бы не пришлось boost::mpl применять.

Во-первых, если код возврата занимает сплошной и не очень широкий диапазон (до 32 значений), можно каждому значению сопоставить 1 бит, через экспонирование: maskbit = 1<<value.
Во-вторых, часть забот можно переложить на рантайм: некая функция, отображающая значения на узкий диапазон "уровней критичности" (например).

А упражнения с mpl — скажем, отображение _множества_ чисел на тип — это по вкусу Хотя и очень красиво, должно быть. some_int_set<ID_Yes,No,Cancel> вместо Mask_Ok|Mask_No|Mask_Cancel... пойду, поиграюсь с компилятором
Перекуём баги на фичи!
Re[7]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 07.07.05 17:04
Оценка: +2
eao197,

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


Проблема в долгой жизни кода. В момент написания (обычно) ошибок в таких простых местах не делают. А вот когда начинается свистопляска с изменениями, да еще и через 2-3 и более лет после изначального написания, плюс целого ряда предшествовавших изменений, и уже давно не в том проекте, в который код входил изначально, и уже совсем не в том контексте... В общем, получается то, что получается. Без помощи компилятора очень легко пропустить какое-нибудь место, особенно, если один из исходников, где используется данная функция, не входит в текущий проект. А с учетом того, что обработку исключительных ситуаций тестировать сложнее, чем основное поведение, то и отлавливаются такие ошибки далеко не всегда. В итоге за время жизни кода, которое может легко и до 10 лет доходить, таки накапливаются ошибки. И ошибок тем больше, чем больше кода, который работает с данной подсистемой. В нашем случае функциональность, связанная с операциями, использующими communicators, является ядром проекта,
соответственно, кода вокруг этого дела вполне достаточно, плюс, в отличие от приведенных примеров, операции нетривиальны, а надежность обработки многообразных исключительных ситуаций очень важна, т.к. в противном случае пользователи легко потеряют свои данные.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[10]: Нужно ли документировать код?
От: IT Россия linq2db.com
Дата: 07.07.05 14:43
Оценка: 23 (1)
Здравствуйте, Кодт, Вы писали:

IT>>Так импорт как раз и оборачивает все возвраты в исключения, плюс выковыривает дополнительную информацию об ошибке из IErrorInfo (или как там его).


К>Ссылочку или хотя бы кейворд для гугления не дашь?


http://www.rsdn.ru/article/vcpp/import.xml
Автор(ы): Игорь Ткачёв
Дата: 9.03.2001

В данной статье приводится объяснение работы директивы #import
компилятора Visual C++ и даны примеры её использования с
MS Word, MS Excel, ADO DB и ActiveX Control.
... << RSDN@Home 1.1.4 stable rev. 510>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[14]: Нужно ли документировать код?
От: IT Россия linq2db.com
Дата: 07.07.05 16:20
Оценка: 23 (1)
Здравствуйте, Кодт, Вы писали:

IT>>Нету. А ты используешь кросплатформенный COM?


К>Угу. Торнадовский VxDCOM, обработанный напильником (вот этими самыми руками).


Кстати, может попробовать таким же напильником обрабатывать tli и tlh файлы? Всё таки код генерируемый, может получится на него натравить регекспы и заменитть чем-нибудь несовместимые места.
... << RSDN@Home 1.1.4 stable rev. 510>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 07.07.05 14:35
Оценка: 10 (1)
Здравствуйте, eao197, Вы писали:

E>>>А во что это все превратиться, если потребуется новые коды возврата добавить? timedout, например?


К>>В пересмотр всей программы. Если изменился контракт объекта (он стал возвращать новые значения), то есть смысл во всех точках вызова убедиться, что эти новые значения корректно обработаны. Здесь компилятор просто заставит это сделать


E>Да это-то я понимаю. Мне просто интересно, хорошо ли это? Нет ли здесь попытки замутить сознание в тривиальном, в общем-то, случае?


Даже в процессе перевода на "новую систему" было найдено две ошибки с необрабатываемыми кодами возврата, плюс одна, связанная с тем, что две реализации одной функции в разных наследниках интерфейса возвращали разный результат для обозначения одного и того же. Тестирование эти ошибки не поймало, т.к. очевидно включает не все возможные комбинации исключительных ситуаций, равно как и все возможные реакции пользователя на них, а ошибки проявлялись только при относительно сложных ситуациях, когда возникала одна исключительная ситуация, и только уже после ее устранения возникала еще одна, да еще и время играло роль... Далее, в процессе начавшегося рефакторинга иерархии интерфейсов communicators, явное описание ожидаемых результатов зарекомендовало себя еще лучше, диагностируя малейшие несогласовки в ожидаемых и реальных результатах.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Нужно ли документировать код?
От: Патрик  
Дата: 06.07.05 09:01
Оценка: 6 (1)
Что уважаемая общественность думает о необходимости документировать/комментировать код?

Я смотрю, что мнения на этот счёт радикально расходятся

Тут говорят что документировать/комментировать надо:
Re: Есть ли в природе каталогизатор С++ кода...?
Автор: Андрей Коростелев
Дата: 03.07.05

Re[3]: Есть ли в природе каталогизатор С++ кода...?
Автор: bkat
Дата: 02.07.05

Re[5]: Есть ли в природе каталогизатор С++ кода...?
Автор: eao197
Дата: 02.07.05


Например тут — наоборот
http://www.rsdn.ru/Forum/?mid=923441
Автор:
Дата: 30.11.04

http://www.rsdn.ru/Forum/?mid=923441
Автор:
Дата: 30.11.04


Сам я придерживаюсь мнения о том, что во многом наличие/отсутствие документации зависит от культуры организации. В некоторых организациях знания хранятся в головах у сотрудников, в некоторых — в документах ворда. И я лично, плохого в этом не виду ничего.

Например наш проект, средний по размеру (~40 человеко/лет) пережил уже несколько версий, частично сменилась команда которая над ним работает и при всё при этом документации по нему по сути нет никакой, ни по архитектуре, ни по коду. Комментариев в коде нет тоже. И проблем это не вызывает. Обратите внимание, я не говорю что это круто — я лишь говорю, что нам это не доставляет никаких проблем. А если нет разницы — зачем платить больше? (с)

Поэтому, во многом, вопрос к тем кто практикует документирование — а зачем вам это? Что, собственно, вам дают залежи документации? Кто её читает? Или она нужно только для того, что бы унять какие-то страхи менеджмента? Так для этого есть более совершенные методы.
... << RSDN@Home 1.1.3 stable >>
Re[6]: Нужно ли документировать код?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.07.05 11:42
Оценка: 1 (1)
Здравствуйте, Кодт, Вы писали:

E>>Да это-то я понимаю. Мне просто интересно, хорошо ли это? Нет ли здесь попытки замутить сознание в тривиальном, в общем-то, случае?


К>Ничего себе тривиальный.


Вообще-то я говорил именно про пример с "Нефиг, Нафиг, Пофиг" (т.е. Abort/Retry/Ignore). Имеет ли смысл наворачивать нетривиальные конструкции на шаблонах для таких тривиальных случаев? Будет ли это упрощение или, наоборот, усложнение кода? В конкретно том примере, который привел Павел, мне показалось, что применение шаблонов -- это overkill.

Ты же приводишь пример с COM, который явно в другой весовой категории.
Я в таких случаях иногда делал функции check_<some_lib> и пропускал все вызовы через них. А там проверял код возврата и генерировал исключения.
И вот в таких случаях подход Павла мне показался интересным. Только вот что делать, если коды возврата нельзя по битовой маске объединять, т.к. они являются простыми перечислениями? Как бы не пришлось boost::mpl применять.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Нужно ли документировать код?
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 06.07.05 09:20
Оценка: +1
Здравствуйте, Патрик, Вы писали:

П>Что уважаемая общественность думает о необходимости документировать/комментировать код?


Очень много зависит от решаемой задачи. Иной код самодостаточный. А в случае реализации сложного алгоритма надо хотя бы ссылку на источник привести А если написанию кода предшествовали математические выкладки, то это может помочь сэкономить преемнику массу времени
... << RSDN@Home 1.1.3 stable >>
Re: Нужно ли документировать код?
От: Патрик  
Дата: 06.07.05 09:25
Оценка: :)
Здравствуйте, Патрик, Вы писали:

П>Что уважаемая общественность думает о необходимости документировать/комментировать код?


Сделал голосование: http://www.rsdn.ru/poll/1191.aspx
Автор: Патрик
Дата: 06.07.05
Вопрос: Практикуется ли в Вашей компании (или отделе) документирование и комментирование кода?
... << RSDN@Home 1.1.3 stable >>
Re[3]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 07.07.05 14:43
Оценка: +1
Здравствуйте, bkat, Вы писали:

B>Почему-то пример в итоге свелся к "нужно ли комментировать код".

B>Это не совсем то же самое, что и "документировать код".

B>Чем меня сразу покорил тот же boost, так это именно своей документацией. <...>


У меня с документацией, подобной бустовской, не ассоциируется слово "код" в том смысле, что для меня это не документирование кода
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[13]: Нужно ли документировать код?
От: Кодт Россия  
Дата: 07.07.05 15:36
Оценка: :)
Здравствуйте, IT, Вы писали:

IT>Нету. А ты используешь кросплатформенный COM?


Угу. Торнадовский VxDCOM, обработанный напильником (вот этими самыми руками).
Перекуём баги на фичи!
Re[14]: Нужно ли документировать код?
От: IT Россия linq2db.com
Дата: 07.07.05 15:50
Оценка: +1
Здравствуйте, Кодт, Вы писали:

IT>>Нету. А ты используешь кросплатформенный COM?


К>Угу. Торнадовский VxDCOM, обработанный напильником (вот этими самыми руками).


Мужчина!
... << RSDN@Home 1.1.4 stable rev. 510>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.07.05 17:14
Оценка: :)
Здравствуйте, IT, Вы писали:

IT>http://www.rsdn.ru/article/vcpp/import.xml
Автор(ы): Игорь Ткачёв
Дата: 9.03.2001

В данной статье приводится объяснение работы директивы #import
компилятора Visual C++ и даны примеры её использования с
MS Word, MS Excel, ADO DB и ActiveX Control.


Я вот подумал... прикинь как мы раньше мучались. А ведь многие и до сих пор над собой издеваются.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 08.07.05 22:24
Оценка: +1
VladD2,

> ПК>Этого недостаточно: не будут диагностироваться ошибки, связанные с расширением этих перечислений. http://rsdn.ru/forum/?mid=1263523
Автор: Павел Кузнецов
Дата: 08.07.05

>
> А что гарантирует от того, что в if новые элементы незабудут впихнуть?

Ничего, но это уже совсем другое дело: если человек меняя тип локальной переменной, не просмотрит тут же присутствующие места, где она используется, то с тем же успехом оно может и пустую ветку if добавить. Это уже халатность. При изменении кода необходимо верифицировать корректность предусловий, при изменении предусловий — корректность кода...

> Это что, такая извращенная замена контекстному поиску? Ну, изменяй названия типа когда добавляешь новые элементы. Эффект будет тот же.


Не будет. Забыть изменить название можно полениться, или не знать о том, что это нужно делать. Тут код полностью направляет в правильном направлении. Плюс, изменение имен типов не решает проблем с объединением наборов значений, как уже было описано ранее.

> А это все примочки. Да и банальный дефолт в свитче в рантайме выдаст исключение.


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

В общем, если хочешь привести конкретный пример более удачного решения описанной проблемы — давай, я с удовольствием посмотрю. Иначе я обсуждение со своей стороны заканчиваю.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[4]: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 11.07.05 23:28
Оценка: -1
Здравствуйте, Павел Кузнецов, Вы писали:

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

ПК>
ПК>. . .

ПК>if ( file_exists( destination_path ) )
ПК>{
ПК>  CommunicatorAnswer< communicator_cancel | communicator_skip | communicator_overwrite >
ПК>    a = communicator.destination_file_already_exists( destination_path );

ПК>  if ( a == communicator_overwrite )
ПК>  {
    this->>delete_file( destination_path );
ПК>  }
ПК>  else
ПК>  {
    this->>mark_failed( source_path );

ПК>    return a == communicator_cancel
ПК>      ? operation_dont_process_remaining_files
ПК>      : operation_process_remaining_files;
ПК>  }
ПК>}

this->>copy_file( source_path, destination_path );
this->>update_db( file_id );

ПК>. . .
ПК>

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

Проблема не решается. И ты это знашь. Вынесение реакции в отдельный класс только разгрзит прикладной код в котором останется всего лишь вызов этого класса. Ну, и главное. Проблема дейсвительно будет решена. И не какими-то малопонятными равартотами, а примитивным и стало быть всем понятным ООП.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Нужно ли документировать код?
От: Патрик  
Дата: 06.07.05 09:31
Оценка:
Здравствуйте, eao197, Вы писали:


E>Ну если нет разницы, то действительно, зачем платить больше?

E>Пока гром не гремит, зачем креститься-то?

Дык уж несколько лет не гремит, и не только у меня

E>Сам я убедился в том, что документировать код нужно обязательно когда потребовалось одновременно вести три или четыре проекта, быстро и неожиданно переключаясь с одного проекта на другой. Тогда лично моих способностей держать в голове кучу деталей по всем проектам просто не хватило. Я элементарно забывал, что писал в каком-то проекте пару дней назад. Не говоря уже про код, написанный несколько месяцев назад.


Ты один их писал? Или были какие-то подчинённые? Если были — то наверное стоило делегировать им бОльшую часть работы и заниматься лишь их контролем...? Хотя, я конечно, не в курсе конкретной ситуации, поэтому воздержусь от особых комментариев.
... << RSDN@Home 1.1.3 stable >>
Re[3]: Нужно ли документировать код?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 06.07.05 09:37
Оценка:
Здравствуйте, Патрик, Вы писали:

П>Здравствуйте, eao197, Вы писали:



E>>Ну если нет разницы, то действительно, зачем платить больше?

E>>Пока гром не гремит, зачем креститься-то?

П>Дык уж несколько лет не гремит, и не только у меня


Так я и говорю, если не гремит, то чего уж выделываться.

E>>Сам я убедился в том, что документировать код нужно обязательно когда потребовалось одновременно вести три или четыре проекта, быстро и неожиданно переключаясь с одного проекта на другой. Тогда лично моих способностей держать в голове кучу деталей по всем проектам просто не хватило. Я элементарно забывал, что писал в каком-то проекте пару дней назад. Не говоря уже про код, написанный несколько месяцев назад.


П>Ты один их писал?


В том-то и дело, что один. И неприятно было в один прекрасный момент понять, что вот-он рубеж моих способностей. Не такой уж и далекий оказался.

П> Или были какие-то подчинённые? Если были — то наверное стоило делегировать им бОльшую часть работы и заниматься лишь их контролем...?


А вот недавно был как раз такой случай, когда из-за недостаточного количества комментариев в коде одного подчиненного прилось объяснять второму подчиненному, что, как и почему.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: Нужно ли документировать код?
От: Патрик  
Дата: 06.07.05 09:48
Оценка:
Здравствуйте, eao197, Вы писали:

П>> Или были какие-то подчинённые? Если были — то наверное стоило делегировать им бОльшую часть работы и заниматься лишь их контролем...?


E>А вот недавно был как раз такой случай, когда из-за недостаточного количества комментариев в коде одного подчиненного прилось объяснять второму подчиненному, что, как и почему.


У нас это регулярно происходит, и ничего...Объясняем! Коммуникация, однако
... << RSDN@Home 1.1.3 stable >>
Литературное программирование
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 06.07.05 10:11
Оценка:
Вот пример, как на мой взгляд, хорошо задокументированой программы, написаной в стиле литературного программирования. Однако эта, имхо, заслуживающая внимания методология, не получила должного распространения. Почему? Не знаю. Я пробовал написать несколько программ по этой методологии, получалось достаточно забавно.
... << RSDN@Home 1.1.3 stable >>
Re: Нужно ли документировать код?
От: Андрей Коростелев Голландия http://www.korostelev.net/
Дата: 06.07.05 20:38
Оценка:
П>Что уважаемая общественность думает о необходимости документировать/комментировать код?
IMHO прежде всего нужно стремиться к самодокументируемому коду. В идеале должен комментироваться только дизайн (связи между классами и назначение отдельных классов).
В самом самом коде (реализации) должны быть комментированы разве что нестандартные ходы (например, отпимизаця).
Плюс придерживание одинакового стиля кодирования для разных членов проекта.

Знания вполне могут хранятся в головах, когда все сидят на одном и том же проекте долгое время и досконально знают концепwию, которую несет этот проект. Однако, когда начнется переключение между разными проектами (то бишь концепциями), начнут возникать проблемы.
Posted via RSDN NNTP Server 1.9
-- Андрей
Re[2]: Нужно ли документировать код?
От: Шахтер Интернет  
Дата: 07.07.05 02:38
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали: ...

Всё это здорово, конечно, а не проще ли было бы сделать два enum а для кодов возврата двух разных функций?
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 07.07.05 03:35
Оценка:
Шахтер,

> Всё это здорово, конечно, а не проще ли было бы сделать два enum а для кодов возврата двух разных функций?


Когда как... Если есть код, который умеет обрабатывать результаты разных нештатных ситуаций, то, полагаю, все-таки, не проще.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[4]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 07.07.05 04:57
Оценка:
P.S.

>> Всё это здорово, конечно, а не проще ли было бы сделать два enum а для кодов возврата двух разных функций?


ПК>Когда как... Если есть код, который умеет обрабатывать результаты разных нештатных ситуаций, то, полагаю, все-таки, не проще.


Ну и, естественно, мы не получим некоторых существенных достоинств в случае решения, описанного выше: 1) в точке использования не будет видно, что обрабатываются все ситуации; 2) если набор значений, возвращаемых функцией, будет расширен, мы не получим от компилятора никаких подсказок об этом в точках использования. В случае же примера выше, мы явно выражаем происходящее и в месте объявления функции (что она может возвращать), и в месте ее использования (что пользователь ожидает от функции); и компилятор следит за совпадением ожиданий пользователя с тем, что функция возвращает на самом деле.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Нужно ли документировать код?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.07.05 05:51
Оценка:
Здравствуйте, Павел Кузнецов

А во что это все превратиться, если потребуется новые коды возврата добавить? timedout, например?
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: Нужно ли документировать код?
От: Кодт Россия  
Дата: 07.07.05 09:09
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, Павел Кузнецов


E>А во что это все превратиться, если потребуется новые коды возврата добавить? timedout, например?


В пересмотр всей программы. Если изменился контракт объекта (он стал возвращать новые значения), то есть смысл во всех точках вызова убедиться, что эти новые значения корректно обработаны. Здесь компилятор просто заставит это сделать

Впрочем, такую расширяемость можно закладывать заранее: например,
template< unsigned Mask, class OnUnexpected = do_static_assert >
class CommunicatorAnswer
{
  unsigned value_;
public:
  template<unsigned SrcMask, class T >
  CommunicatorAnswer(CommunicatorAnswer<SrcMask, T> src,
                     enable_if_c(
                       (SrcMask & ~Mask)==0, // если маска исходного типа меньше или равна нашей маске
                     void*)::type = NULL
                    )
    : value_(src.value())
  {}

  template<unsigned SrcMask, class T >
  CommunicatorAnswer(CommunicatorAnswer<SrcMask, T> src,
                     enable_if_c(
                       (SrcMask & ~Mask)!=0, // если маска исходного типа больше нашей маски
                     void*)::type = NULL
                    )
    : value_(OnUnexpected()(Mask,src.value())) // выполним замену (или даже получим по рогам при компиляции)
  {}
};

struct do_static_assert
{
  // нет operator() - будет ошибка компиляции
};

static do_runtime_assert
{
  unsigned operator()(unsigned mask, unsigned value) const
  {
    if((value & ~mask) != 0)
      throw logic_error("кривые кирпичи мне подсунули");
    return value;
  }
};

static do_supress
{
  unsigned operator()(unsigned mask, unsigned value) const
  {
    if((value & ~mask) != 0)
      value = /*первый попавшийся ненулевой бит маски*/;
    return value;
  }
};
Перекуём баги на фичи!
Re[4]: Нужно ли документировать код?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.07.05 09:25
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, eao197, Вы писали:


E>>Здравствуйте, Павел Кузнецов


E>>А во что это все превратиться, если потребуется новые коды возврата добавить? timedout, например?


К>В пересмотр всей программы. Если изменился контракт объекта (он стал возвращать новые значения), то есть смысл во всех точках вызова убедиться, что эти новые значения корректно обработаны. Здесь компилятор просто заставит это сделать


Да это-то я понимаю. Мне просто интересно, хорошо ли это? Нет ли здесь попытки замутить сознание в тривиальном, в общем-то, случае?
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Нужно ли документировать код?
От: bkat  
Дата: 07.07.05 09:25
Оценка:
Почему-то пример в итоге свелся к "нужно ли комментировать код".
Это не совсем то же самое, что и "документировать код".

Чем меня сразу покорил тот же boost, так это именно своей документацией.
Я не любитель читать чужие исходные тексты и потому как откомментирован boost,
мне все равно. Для поддержки boost'а вменяемые комментарии могут важными,
ну а а мне как пользователю библиотеки важнее описание что это вообще такое
и как этим добром пользоваться.

А Патрик как раз и спрашивал о подобной общей библиотеке маштаба одной компании.
Ее будет полезно и задокументировать, и откомментировать, и оттестировать
и code review провести...
Re: Нужно ли документировать код?
От: bkat  
Дата: 07.07.05 09:31
Оценка:
Здравствуйте, Патрик, Вы писали:

П>Например тут — наоборот

П>http://www.rsdn.ru/Forum/?mid=923441
Автор:
Дата: 30.11.04


Где там наоборот?
Там у человека проблема, что код как раз бог знает какой
и нет ни комментариев ни описаний.
Он не считает, что так и должно быть.
Re[3]: Нужно ли документировать код?
От: Патрик  
Дата: 07.07.05 09:34
Оценка:
Здравствуйте, bkat, Вы писали:

B>Чем меня сразу покорил тот же boost, так это именно своей документацией.

B>Я не любитель читать чужие исходные тексты и потому как откомментирован boost,
B>мне все равно. Для поддержки boost'а вменяемые комментарии могут важными,
B>ну а а мне как пользователю библиотеки важнее описание что это вообще такое
B>и как этим добром пользоваться.

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

B>А Патрик как раз и спрашивал о подобной общей библиотеке маштаба одной компании.

B>Ее будет полезно и задокументировать, и откомментировать, и оттестировать
B>и code review провести...

Ну не только о ней . Я расширил вопрос до кода вообще.

Но всё таки библиотека масштаба предприятия (или даже отдела) — нечто куда более мелкое.
... << RSDN@Home 1.1.3 stable >>
Re[2]: Нужно ли документировать код?
От: Патрик  
Дата: 07.07.05 09:37
Оценка:
Здравствуйте, bkat, Вы писали:

B>Здравствуйте, Патрик, Вы писали:


П>>Например тут — наоборот

П>>http://www.rsdn.ru/Forum/?mid=923441
Автор:
Дата: 30.11.04


B>Где там наоборот?

B>Там у человека проблема, что код как раз бог знает какой
B>и нет ни комментариев ни описаний.
B>Он не считает, что так и должно быть.

Ооопс...Это я слажал

Имелось ввиду —
http://www.rsdn.ru/Forum/Message.aspx?mid=923677&amp;only=1
Автор: dmz
Дата: 01.12.04

http://www.rsdn.ru/Forum/Message.aspx?mid=926631&amp;only=1
Автор: dmz
Дата: 01.12.04
... << RSDN@Home 1.1.3 stable >>
Re: Нужно ли документировать код?
От: Патрик  
Дата: 07.07.05 11:23
Оценка:
Здравствуйте, Патрик, Вы писали:

П>Что уважаемая общественность думает о необходимости документировать/комментировать код?


Ещё раз прочитав внимательно все ответы, вот что бросилось в глаза: большинство из ответивших замечает только комментирование, в то время как в голосовании, с ощутимым преимуществом побеждает пункт "И документирование и комментирование".

Т.е. документируем тихо матерясь сковь зубы и считая это бесполезным занятием?

Всё таки, те кто считает документацию важной — скажите, зачем она вам? Я видел вариант eao197 только(Re: Нужно ли документировать код?
Автор: eao197
Дата: 06.07.05
)
... << RSDN@Home 1.1.3 stable >>
Re[6]: Нужно ли документировать код?
От: IT Россия linq2db.com
Дата: 07.07.05 13:53
Оценка:
Здравствуйте, Кодт, Вы писали:

К>В конце концов мне надоело, и я переделал некоторые интерфейсы вдребезги пополам. Благо, что COM-объекты внутренние.


Надо было пользоваться чем-нибудь типа #import. Тогда и овцы были бы сыты и волки целы.
... << RSDN@Home 1.1.4 stable rev. 510>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[7]: Нужно ли документировать код?
От: Кодт Россия  
Дата: 07.07.05 14:07
Оценка:
Здравствуйте, IT, Вы писали:

К>>В конце концов мне надоело, и я переделал некоторые интерфейсы вдребезги пополам. Благо, что COM-объекты внутренние.


IT>Надо было пользоваться чем-нибудь типа #import. Тогда и овцы были бы сыты и волки целы.


Дело не в импорте, а в том, что всё возвращалось через единственный тип (HRESULT), создавая путаницу в обработке.
Вдребезги-пополам — это значило не проблемы с пересобиранием (в общем-то, какая разница, импортировать tlb или инклудить сгенерированный h), а то, что компилятор показал мне все места, где HRESULT использовался как YesNo, как OkCancel, как void...
Перекуём баги на фичи!
Re[8]: Нужно ли документировать код?
От: IT Россия linq2db.com
Дата: 07.07.05 14:17
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Дело не в импорте, а в том, что всё возвращалось через единственный тип (HRESULT), создавая путаницу в обработке.


Так импорт как раз и оборачивает все возвраты в исключения, плюс выковыривает дополнительную информацию об ошибке из IErrorInfo (или как там его).
... << RSDN@Home 1.1.4 stable rev. 510>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[9]: Нужно ли документировать код?
От: Кодт Россия  
Дата: 07.07.05 14:26
Оценка:
Здравствуйте, IT, Вы писали:

IT>Так импорт как раз и оборачивает все возвраты в исключения, плюс выковыривает дополнительную информацию об ошибке из IErrorInfo (или как там его).


Ссылочку или хотя бы кейворд для гугления не дашь?
Перекуём баги на фичи!
Re[4]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 07.07.05 14:26
Оценка:
Здравствуйте, Кодт, Вы писали:

E>> А во что это все превратиться, если потребуется новые коды возврата добавить? timedout, например?


К> В пересмотр всей программы. Если изменился контракт объекта (он стал возвращать новые значения), то есть смысл во всех точках вызова убедиться, что эти новые значения корректно обработаны. Здесь компилятор просто заставит это сделать


Именно это и было нужно: если некоторая функция начинает возвращать новый результат, то обязательно нужно исправить всех клиентов. Если функция перестает возвращать один из результатов, то ничего существенного с клиентами в нашем случае делать не нужно: просто одна из веток перестанет выполняться, что не страшно. Для этого достаточно, чтоб CommunicatorAnswer<mask> мог создаваться из CommunicatorAnswer<another_mask> если mask включает в себя все значения, представленные another_mask. Также это удобно, если в некоторой функции сначала определяются все нештатные ситуации, и получается реакция пользователя, а уж затем, в одном месте, обрабатывается полученный ответ. В этом случае можно объявить переменную, маска которой является объединением всех возможных ответов. Соответственно, так и было сделано.

Если бы требования были другими, можно было бы сделать по-другому, введя какую-то другую логику в CommunicatorAnswer. Прелесть в возможности контролируемого управления этими требованиями.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[6]: Нужно ли документировать код?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.07.05 14:41
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

E>>Да это-то я понимаю. Мне просто интересно, хорошо ли это? Нет ли здесь попытки замутить сознание в тривиальном, в общем-то, случае?


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


Спасибо за подробный ответ. Я просто не представлял себе, что такая тривиальная задача, как контроль выбора пользователя из нескольких вариантов может привести к такому количеству ошибок. Чего, однако, в жизни не бывает.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: Нужно ли документировать код?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.07.05 14:44
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Например, из свеженького.


Вот этот бы классик, CommunicatorAnswer, да в виде реюзабильного шаблона, да в open-source виде получить, готовый. И в boost запихнуть.

Чтобы самому велосипеды не плодить.
... << RSDN@Home 1.1.4 stable rev. 510>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: Нужно ли документировать код?
От: Кодт Россия  
Дата: 07.07.05 15:12
Оценка:
Здравствуйте, IT, Вы писали:

IT>http://www.rsdn.ru/article/vcpp/import.xml
Автор(ы): Игорь Ткачёв
Дата: 9.03.2001

В данной статье приводится объяснение работы директивы #import
компилятора Visual C++ и даны примеры её использования с
MS Word, MS Excel, ADO DB и ActiveX Control.


Спасибо. Жаль, что это чисто VC-шная штука. Или, может быть, есть кроссплатформенные тулзы?
Перекуём баги на фичи!
Re[12]: Нужно ли документировать код?
От: IT Россия linq2db.com
Дата: 07.07.05 15:24
Оценка:
Здравствуйте, Кодт, Вы писали:

IT>>http://www.rsdn.ru/article/vcpp/import.xml
Автор(ы): Игорь Ткачёв
Дата: 9.03.2001

В данной статье приводится объяснение работы директивы #import
компилятора Visual C++ и даны примеры её использования с
MS Word, MS Excel, ADO DB и ActiveX Control.


К>Спасибо. Жаль, что это чисто VC-шная штука. Или, может быть, есть кроссплатформенные тулзы?


Нету. А ты используешь кросплатформенный COM?
... << RSDN@Home 1.1.4 stable rev. 510>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[15]: Нужно ли документировать код?
От: Кодт Россия  
Дата: 07.07.05 16:26
Оценка:
Здравствуйте, IT, Вы писали:

IT>Кстати, может попробовать таким же напильником обрабатывать tli и tlh файлы? Всё таки код генерируемый, может получится на него натравить регекспы и заменитть чем-нибудь несовместимые места.


Хорошая мысля приходит опосля. Посмотрю, что из этого выйдет.
Перекуём баги на фичи!
Re[12]: Нужно ли документировать код?
От: Cyberax Марс  
Дата: 07.07.05 17:18
Оценка:
Кодт wrote:

> IT>http://www.rsdn.ru/article/vcpp/import.xml
Автор(ы): Игорь Ткачёв
Дата: 9.03.2001

В данной статье приводится объяснение работы директивы #import
компилятора Visual C++ и даны примеры её использования с
MS Word, MS Excel, ADO DB и ActiveX Control.

> <http://rsdn.ru/article/vcpp/import.xml&gt;
Автор(ы): Игорь Ткачёв
Дата: 9.03.2001

В данной статье приводится объяснение работы директивы #import
компилятора Visual C++ и даны примеры её использования с
MS Word, MS Excel, ADO DB и ActiveX Control.

> Спасибо. Жаль, что это чисто VC-шная штука. Или, может быть, есть
> кроссплатформенные тулзы?

Какая кроссплатформенность с COM?

Хотя есть Comet: http://lambdasoft.dk/Comet/ — оно собирается под GCC, и
вообще намного приятнее #import'а.

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[7]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 07.07.05 18:13
Оценка:
eao197,

> E>> Да это-то я понимаю. Мне просто интересно, хорошо ли это? Нет ли здесь попытки замутить сознание в тривиальном, в общем-то, случае?


> К> Ничего себе тривиальный.


> Вообще-то я говорил именно про пример с "Нефиг, Нафиг, Пофиг" (т.е. Abort/Retry/Ignore). Имеет ли смысл наворачивать нетривиальные конструкции на шаблонах для таких тривиальных случаев? Будет ли это упрощение или, наоборот, усложнение кода? В конкретно том примере, который привел Павел, мне показалось, что применение шаблонов -- это overkill.


Ага... Кажется, я понял, где пример "недоплюнул" до реальной жизни...

Abort/Retry/Ignore — только один из возможных вариантов. И не факт, что завтра в этом же месте по-прежнему пользователю будет предоставлен именно такой выбор. Допустим, вчера было "Destination file exists. Abort/Retry/Ignore", а сегодня стало "Destination file exists. Replace? Abort/No/Yes", т.к. было решено, что так пользователю будет намного понятнее. Если код привязан непосредственно к вариантам, показываемым пользователю (Abort/Retry/Ignore vs. Abort/No/Yes), то все вообще плохо, т.к. вероятность внесения ошибок при последующих изменениях очень высока. Скажем, даже не изменяя варианты, можно изменить смысл некоторых из них, изменив вопрос, задаваемый пользователю: "Destination file exists. Skip? Abort/No/Yes", т.к., например, было решено, что предлагать деструктивное действие неправильно. (мотивация в данном случае берется с потолка, очевидно, что в реальной жизни причины бывают самые разные)

Соответственно, от "названий кнопок" нужно абстрагироваться обязательно, так чтобы функции-члены communicators, с которыми имеет дело логика операции, возвращали нечто в терминах операции, а не в терминах ответа пользователя: abort, skip, continue — вне зависимости от формулировок вопросов и предоставленных пользователю вариантов — означает, что, собственно, должна делать операция.

Но этого шага самого по себе недостаточно, т.к., как говорилось, доступные варианты действий могут меняться. Сегодня мы не умеем пропускать файлы при копировании, поэтому вариантов всего два (abort, continue), а завтра научимся — и нужно будет добавить еще один вариант (skip). Но мест, в которых содержится вызов данной функции, задающей вопрос пользователю, может быть много, соответственно, нужно обеспечить, чтоб поведение между всеми этими местами было согласованным.

Если же идти по другому пути — отдельная функция для каждого подобного места, — то ситуация тоже не лучше, в других аспектах: очень тяжело обеспечивать единообразие всех подобных случаев. Иначе пользователь может быть очень сильно удивлен, что в одном месте ему предлагают пропустить конфликтующий файл, а в другом — нет. Плюс, первоначальная проблема не решается в другом случае: реализаций данного интерфейса более одной (см. ниже), и, соответственно, нужно заботиться о соблюдении ими контракта (все реализации одной и той же функции должны возвращать согласованный набор результатов).

Если же идти еще по другому пути, не вводя прослойку в виде communicators, то мы не покроем целый ряд use cases, когда те же операции работают в несколько ином окружении, где с пользователем взаимодействовать нельзя, а варианты действий на все нештатные ситуации задаются заранее, скажем, опциями командной строки, конфигурационными файлами или еще как-нибудь. Плюс, мы намного осложним сопровождение кода, связав "логический" уровень с презентационным.

Приведенный подход решает все упомянутые проблемы.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 07.07.05 18:38
Оценка:
eao197,

> ПК> Например, из свеженького.


> Вот этот бы классик, CommunicatorAnswer, да в виде реюзабильного шаблона, да в open-source виде получить, готовый. И в boost запихнуть.

>
> Чтобы самому велосипеды не плодить.

На самом деле, если идти дальше, то в общем случае одного значения enum в качестве результата выбора может быть недостаточно, вполне возможно, что, кроме кода выбранного варианта, желательно иметь какие-то дополнительные данные. Скажем, все на том же примере конфликтующих файлов при копировании, вполне может захотеться усложнить взаимодействие с пользователем и предоставить вариант скопировать файл под новым именем. В этом случае было бы разумно вернуть из Communicator в операцию это самое новое имя. Т.е. более общим подходом будет что-нибудь типа boost::variant параметризованный классами, представляющими соответствующие варианты действий. Часть из этих классов может быть пустой, просто обозначая сам выбор (например, Abort).

Собственно, в какой-то момент была предпринята попытка перейти от:
CommunicatorAnswer< communicator_abort | communicator_retry | communicator_ignore > answer;

к
boost::variant< CommunicatorAbort, CommunicatorSkip, CommunicatorOverwrite > answer;

но, к сожалению, в текущей реализации boost::variant обнаружился существенный для нашего use case недостаток: boost::variant не диагностирует во время компиляции извлечь из него значение, не входящее в список хранимых в нем типов. Т.е. для объявления выше следующее не приводит к ошибке компиляции:
if ( get< CommunicatorRename >( &answer ) )
   . . .

Также не выяснялся вопрос поддержки остальных описанных в теме use cases в boost::variant. Соответственно, пока переход к boost::variant отменен (*). Но в принципе, подход, основанный на использовании boost::variant или аналогичного класса мне кажется более общим и перспективным для данной задачи.

Собственно, пример с CommunicatorAnswer это пример того, как можно переводить комментарии в код, еще и получая целый ряд приятных бонусов. boost::variant или какой-нибудь более строгий аналог можно считать дальнейшим развитием этого подхода, и идее явного задания контрактов в коде он не противоречит, скорее ее дополняет...

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



(*) Хотя есть достаточно дешевые способы сделать к нему свои переходники, исправляющие найденные недочеты, но о них мысли появились уже потом — может, когда понадобится возвращать что-нибудь, кроме кода сделанного выбора, все-таки к нему и перейдем. Может, к тому времени он даже будет исправлен нужным образом
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[4]: Нужно ли документировать код?
От: bkat  
Дата: 07.07.05 19:13
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:


ПК>У меня с документацией, подобной бустовской, не ассоциируется слово "код" в том смысле, что для меня это не документирование кода


Хорошо, документация, подобной бустовской — это конечно больше manual.
Что тогда "документирование кода"?
Неужто только комментарии и красивый код сам по себе?
Re[5]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 07.07.05 20:04
Оценка:
bkat,

> ПК> У меня с документацией, подобной бустовской, не ассоциируется слово "код" в том смысле, что для меня это не документирование кода

>
> Хорошо, документация, подобной бустовской — это конечно больше manual.
> Что тогда "документирование кода"?
> Неужто только комментарии и красивый код сам по себе?

Я различаю "документирование кода" и "комментирование кода" только местом размещения документации: в первом случае это может быть не только в комментариях непосредственно в исходном коде, но и где-то еще. Другое дело, что, кроме документирования кода, может потребоваться и другая документация, относящаяся к процессу разработки: требования, спецификация, документация окружения, документ, описывающий соглашения о кодировании, всевозможные rationale для архитектурных решений т.д., и т.п.
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.07.05 17:14
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

Почему был не завести два перечисления?

Что же до символов в качестве результата функции, то за такое морду нужно бить (сильно).
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.07.05 17:14
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Спасибо. Жаль, что это чисто VC-шная штука. Или, может быть, есть кроссплатформенные тулзы?


Борланд частично поддерживает. Но это дело генерирует обертки на чистом С++ вроде бы.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 08.07.05 17:28
Оценка:
VladD2,

> Почему был не завести два перечисления?


Этого недостаточно: не будут диагностироваться ошибки, связанные с расширением этих перечислений. http://rsdn.ru/forum/?mid=1263523
Автор: Павел Кузнецов
Дата: 08.07.05
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: Нужно ли документировать код?
От: achp  
Дата: 08.07.05 17:32
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Что же до символов в качестве результата функции, то за такое морду нужно бить (сильно).


И разработчикам lex и yacc тоже?
Re[13]: Нужно ли документировать код?
От: IT Россия linq2db.com
Дата: 08.07.05 18:25
Оценка:
Здравствуйте, VladD2, Вы писали:

К>>Спасибо. Жаль, что это чисто VC-шная штука. Или, может быть, есть кроссплатформенные тулзы?


VD>Борланд частично поддерживает. Но это дело генерирует обертки на чистом С++ вроде бы.


Импорт использует расширение компилятора для объявления пропертей.
... << RSDN@Home 1.1.4 stable rev. 510>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[14]: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.07.05 20:48
Оценка:
Здравствуйте, IT, Вы писали:

IT>Импорт использует расширение компилятора для объявления пропертей.


Ну, это макросами лечится. К тому же борланд и многие другие вроде их тоже поддерживают.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.07.05 20:48
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Этого недостаточно: не будут диагностироваться ошибки, связанные с расширением этих перечислений. http://rsdn.ru/forum/?mid=1263523
Автор: Павел Кузнецов
Дата: 08.07.05


А что гарантирует от того, что в if новые элементы незабудут впихнуть?

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

ЗЫ

Если уж волнует согласованность изменений, то есть только два 100%-ых способа:
1. Довести все до декларативности избавишись от необходимости описывать что-то в двух местах. Так, например, сделаны меню и тулбары в Хоуме.
2. Иметь некоторые средства тестирования позволяющих описать правила проверки. Ну, ты полян на что я намекаю.

А это все примочки. Да и банальный дефолт в свитче в рантайме выдаст исключение. А синтаксис у тебя получается ужастным. Копипэст чистой воды, да еще и длинный как черт знает что.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.07.05 20:48
Оценка:
Здравствуйте, achp, Вы писали:

VD>>Что же до символов в качестве результата функции, то за такое морду нужно бить (сильно).


A>И разработчикам lex и yacc тоже?


Ты действительно не понял о чем я говрил?
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[15]: Нужно ли документировать код?
От: IT Россия linq2db.com
Дата: 08.07.05 20:54
Оценка:
Здравствуйте, VladD2, Вы писали:

IT>>Импорт использует расширение компилятора для объявления пропертей.


VD>Ну, это макросами лечится. К тому же борланд и многие другие вроде их тоже поддерживают.


У них у всех свои расширения.
... << RSDN@Home 1.1.4 stable rev. 510>>
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Нужно ли документировать код?
От: achp  
Дата: 10.07.05 18:04
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ты действительно не понял о чем я говрил?


О неком непреложном правиле. Нет?
Re[6]: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.07.05 18:41
Оценка:
Здравствуйте, achp, Вы писали:

A>Здравствуйте, VladD2, Вы писали:


VD>>Ты действительно не понял о чем я говрил?


A>О неком непреложном правиле. Нет?


Бывает. Объясняю...

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

Если lex и yacc делают так же, то несомненно это кривой дизайн. Но, насколько мне известно, они так не делают. Они используют char для возврата символов.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 10.07.05 20:10
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

Так что же помешало использовать паттерн "Стратегия" для решения данной задачи? Только отговорку — объем кода не нужно приводить. Я тут еще раз подумал и пришел к выводу, что общий объем кода даже сократится.
... << RSDN@Home 1.1.4 beta 7 rev. 466>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Нужно ли документировать код?
От: Павел Кузнецов  
Дата: 11.07.05 01:11
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Так что же помешало использовать паттерн "Стратегия" для решения данной задачи? Только отговорку — объем кода не нужно приводить. Я тут еще раз подумал и пришел к выводу, что общий объем кода даже сократится.


Именно объем кода, приводящий к осложнению понимания происходящего, что осложняет дальнейшее сопровождение (вопреки изначальному желанию это упростить).

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

if ( file_exists( destination_path ) )
{
  CommunicatorAnswer< communicator_cancel | communicator_skip | communicator_overwrite >
    a = communicator.destination_file_already_exists( destination_path );

  if ( a == communicator_overwrite )
  {
    this->delete_file( destination_path );
  }
  else
  {
    this->mark_failed( source_path );

    return a == communicator_cancel
      ? operation_dont_process_remaining_files
      : operation_process_remaining_files;
  }
}

this->copy_file( source_path, destination_path );
this->update_db( file_id );

. . .

надо будет навернуть класс, в который нужно будет как-то передавать контекст исполнения (например, чтоб вызвать mark_failed), да еще и как-то заботиться о том, чтобы из него потом все равно получить в том или ином виде информацию о том, нужно ли продолжать исполнение и т.п. И, главное, зачем, если реальная проблема (неожиданное добавление новых возвращаемых значний в destination_file_already_exists) решается просто, не требуя никаких дополнительных усилий у пользователей функции?
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[7]: Нужно ли документировать код?
От: achp  
Дата: 20.07.05 15:26
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Если lex и yacc делают так же, то несомненно это кривой дизайн. Но, насколько мне известно, они так не делают. Они используют char для возврата символов.


А вот и не для возврата символов! Для передачи лексем, которые в исходном коде представляются одиночными символами. То есть, с формальной точки зрения, дизайн некорректный. А с практической — вполне удобный.
Re[8]: Нужно ли документировать код?
От: VladD2 Российская Империя www.nemerle.org
Дата: 22.07.05 13:04
Оценка:
Здравствуйте, achp, Вы писали:

A>А вот и не для возврата символов! Для передачи лексем, которые в исходном коде представляются одиночными символами. То есть, с формальной точки зрения, дизайн некорректный. А с практической — вполне удобный.


Ой, давно я их смотрел. Но что-то мне подсказывает, что там используется int. И никаких запаковок констант в символы не происходит.

Но пользоваться Яками не очень удобно. Схема принятая в CocoR или ANTLR намного лучше (там можно просто объявлять именованные переменные и возвращать параметры из правил).
... << RSDN@Home 1.2.0 alpha rev. 578>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.