Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизО стиле "неубиваемого" кода. Найти похожие ветки
← →
Дмитрий С © (2012-06-27 00:28) [0]Предлагаю похолливарить на следую тему:
Есть, к примеру некая функция. Внутри нее множество вызовов, результат каждого из которых нужно проверять.
Способ с исключениями и try finally я хочу исключить сразу, но не потому что он плох, а потому что, хочу обсудить два других варианта (в том языке для которого я интересуюсь не принято try finally).
И так вариант первый:
- Вложенные условия.
if foo() = 0 then
begin
file = file_open(...);
if file <> 0 then
begin
... // штук 10 вложений
result = "ok";
...
file_close(file);
end else begin
result = "CANNOT_OPEN_FILE";
end;
end else begin
result = "FOO_FAILED";
end;
И другой:
- С выходом.
label exit_point;
file = 0;
if foo() <> 0 then
begin
result = "FOO_FAILED";
goto exit_point;
end;
file = file_open(...);
if file = 0 then
begin
result = "CANNOT_OPEN_FILE";
goto exit_point;
end;
... // штук 10 подобных вызовов
exit_point:
if file <> 0 then close_file(file);
Собственное интересует ваше мнение о том и другом.
P.S. Вариант "Не писать такие большие функции" не предлагать. Иногда надо.
← →
antonn © (2012-06-27 00:52) [1]а в чем "холливарность"?
← →
Jeer © (2012-06-27 01:31) [2]
> Собственное интересует ваше мнение о том и другом.
Мнение простое - делай как тебе удобнее и понятнее, лишь бы работало.
← →
Германн © (2012-06-27 01:33) [3]
> Собственное интересует ваше мнение о том и другом.
>
Я предпочитаю второй вариант. (Для тех двух других языков, которыми я занимался довольно плотно :).
← →
Германн © (2012-06-27 01:39) [4]
> antonn © (27.06.12 00:52) [1]
>
> а в чем "холливарность"?
Автору только кажется, что тут возможен холивар. Имхо, из-за использования goto, что для Паскаля считается дурным тоном.
← →
Ega23 © (2012-06-27 03:57) [5]На TSQL я второй вариант практически всегда использовал.
Да и в других случаях при отсутствии finally - тоже также поступил бы, скорее всего.
"Холиварность" - сомнительная, ИМХО, писать надо так, как тебе удобнее.
← →
tesseract © (2012-06-27 08:25) [6]
> file = file_open(...);
> if file = 0 then
> begin
> result = "CANNOT_OPEN_FILE";
> goto exit_point;
> end;
Goto ? Эцих с гвозьдями!
file = file_open(...);
if file <> 0 then
Понятнее как-то так :
var sUserMsg :string;
file = file_open(...);
If not CheckFileOpenResult(file,sUserMsg) then Exception.Create(sUserMsg);
← →
Ega23 © (2012-06-27 08:29) [7]
> Goto ? Эцих с гвозьдями!
Почему?
← →
Омлет © (2012-06-27 08:30) [8]> в том языке для которого я интересуюсь не принято try finally
Ну так яви название языка.
← →
И. Павел © (2012-06-27 08:46) [9]> в том языке для которого я интересуюсь не принято try finally
Уж не ABAP ли? По моему это один из немногих современных языком, который упорно не хочет выбираться из эпохи диско :)
← →
Думкин © (2012-06-27 08:50) [10]Ну, на Х++ try catch только. finally нет.
← →
Омлет © (2012-06-27 09:17) [11]"не принято" != "нет"
← →
Sha © (2012-06-27 09:23) [12]Когда вложений мало (до 3-4) - первый.
Много или сложные IFы - второй. Главное выбрать единый стиль написания выхода по ошибке и формирования кода ошибки.
← →
Думкин © (2012-06-27 09:24) [13]Это понятно. Но сама фраза странная "не принято". Над принимать ставки на то, что именно вкладывал автор в эти поэтичные строки.
← →
Cobalt © (2012-06-27 09:28) [14]может, это PHP?
← →
Омлет © (2012-06-27 09:37) [15]> может, это PHP?
Там нет finally.
← →
oxffff © (2012-06-27 10:31) [16]
> И. Павел © (27.06.12 08:46) [9]
> > в том языке для которого я интересуюсь не принято try
> finally
>
> Уж не ABAP ли? По моему это один из немногих современных
> языком, который упорно не хочет выбираться из эпохи диско
> :)
Не надо ля-ля.
В ABAP есть структурная обработка исключений.
← →
И. Павел © (2012-06-27 10:51) [17]> В ABAP есть структурная обработка исключений.
Есть, я и не писал, что нет. Но операторы (например, SELECT) возвращают результат своего выполнения через флаг...
← →
Компромисс © (2012-06-27 11:02) [18]Разделение на функции поможет
f = openFile(file);
if(f == 0){
...
return;
}
processingResult = processFile(f);
closeFile(f);
в processFile будет
if foo() <> 0 then
return "FOO_FAILED";
end;
...
... // штук 10 подобных return;
← →
tesseract © (2012-06-27 11:09) [19]
> в processFile будет
> if foo() <> 0 then
> return "FOO_FAILED";
> end;
Лучше всё таки выдавать ошибку по GetLastError. Таки правильнее.
← →
oxffff © (2012-06-27 11:17) [20]
> И. Павел © (27.06.12 10:51) [17]
> > В ABAP есть структурная обработка исключений.
>
> Есть, я и не писал, что нет. Но операторы (например, SELECT)
> возвращают результат своего выполнения через флаг...
Если ты про OPEN SQL. То не только через SY-SUBRC.
Он еще может вываливаться в исключение.
Например CX_SY_OPEN_SQL_DB.
← →
oxffff © (2012-06-27 11:20) [21]По теме.
Использую и тот и другой варианты.
← →
Компромисс © (2012-06-27 11:30) [22]
> Лучше всё таки выдавать ошибку по GetLastError. Таки правильнее.
Конечно. Но только если GetLastError применим. Может, человек на PHP каком-нибудь работает...
Еще правильнее try-finally использовать.
Если в языке есть try-finally, то его нужно использовать всегда, когда есть смысл. На моду нельзя ориентироваться, это не одежда :-)
Если только "мода" не вызвана тем, что try-finally не всегда правильно работает из-за багов в реализации языка.
← →
Компромисс © (2012-06-27 11:42) [23]Чем мне не нравятся оба варианта автора, так это тем, что чем больше if, тем хуже читабельность. В первом случае отступы могут стать гигантскими, во втором случае метка окажется через N страниц от первого if.
← →
RWolf © (2012-06-27 11:45) [24]Компромисс © (27.06.12 11:42) [23]
это естественный ограничитель длины функции )
← →
tesseract © (2012-06-27 11:48) [25]
> Еще правильнее try-finally использовать.
А причем тут try..finally и выдача грамотных сообщений об ошибке? Raise можно преспокойно сделать с API-шной FormatMessage и вызвать исключение с читабельной ошибкой.
← →
Плохиш © (2012-06-27 11:54) [26]
> Дмитрий С © (27.06.12 00:28)
Ни в первом, ни во втором варианте goto нафик не нужно, так же как и возбуждение собственных исключений.
При работе с файлами без обработки исключительных ситуаций не обойтись.
← →
Компромисс © (2012-06-27 12:01) [27]
> А причем тут try..finally и выдача грамотных сообщений об
> ошибке?
Я к тому, что если уж автора учить, то неиспользование try-finally - более грубая ошибка, чем неиспользование GetLastError.
> Raise можно преспокойно сделать с API-шной FormatMessage
> и вызвать исключение с читабельной ошибкой.
Я сейчас на яве работаю, мне FormatMessage кажется неправильным, потому как с локализацией тяжело будет. Только код сообщения об ошибке, никаких текстов ошибок в программе.
← →
tesseract © (2012-06-27 12:13) [28]
> Я сейчас на яве работаю, мне FormatMessage кажется неправильным,
> потому как с локализацией тяжело будет.
Вообще она юникодовая. В WinAPI.
← →
Компромисс © (2012-06-27 12:20) [29]tesseract © (27.06.12 12:13) [28]
Замечательно.
1) Можно текст сообщения об ошибке заменить, не перекомпилируя приложение?
2) Можно добавить новый поддерживаемый язык, не перекомпилируя приложение?
Только не надо в каждый raise добавлять параметр для FormatMessage, неправильно это.
raise должен использовать код типа "file.not.found", а уже самый верхний обработчик ошибок должен подставлять нужное значение текста ошибки в зависимости от кода ошибки и от языка пользователя.
← →
DVM © (2012-06-27 12:26) [30]
> GetLastError
> FormatMessage
Win32Check не проще?
← →
Дмитрий С © (2012-06-27 13:11) [31]
> Может, человек на PHP каком-нибудь работает...
Вот-вот. В нем и finally нет, реализация функций убогая (для скриптового языка)
> во втором случае метка окажется через N страниц от первого
> if.
Ну это да. Но по названию метки понятно что это за метка да и раз посмотреть можно что там внизу.
> то неиспользование try-finally - более грубая ошибка,
Ну нет finally в языке, что сделаешь то, да и большинство функций не генерируют исключения. А некоторые еще и ошибку через одно место возвращают.
> Только код сообщения об ошибке, никаких текстов ошибок
> в программе.
Т.е. пользователю нужно будет связываться с поддержкой или утомительно читать хелп, чтобы понять что за ошибка номер 42, вместо того, чтобы хоть как то натолкнуть его на мысль в чем может быть дело?
← →
Компромисс © (2012-06-27 13:47) [32]
> Т.е. пользователю нужно будет связываться с поддержкой или
> утомительно читать хелп, чтобы понять что за ошибка номер
> 42, вместо того, чтобы хоть как то натолкнуть его на мысль
> в чем может быть дело?
Нет. Код генерирует ошибку с кодом file.not.found и параметром, установленным в имя файла, ошибка в конце концов передается функции, которая находит текст сообщения по ошибке в файле errors.properties:
file.not.found=Cannot find file with name %s
Точнее, если у пользователя текущая локаль ru_ru, то сначала происходит поиск файла error_ru_RU.properties, потом errors_ru.properties и только потом errors.properties
← →
tesseract © (2012-06-27 14:14) [33]
> 1) Можно текст сообщения об ошибке заменить, не перекомпилируя
> приложение?
> 2) Можно добавить новый поддерживаемый язык, не перекомпилируя
> приложение?
Можно только получать тескт ошибки специфичной для данной оси. Это приятно пользователю. Дальше - это уже грамотные навороты.
> Точнее, если у пользователя текущая локаль ru_ru, то сначала
> происходит поиск файла error_ru_RU.properties
ИМХО BerkleyDB базы всё-таки практичнее при большом количестве сообщений.
← →
Компромисс © (2012-06-27 14:41) [34]
> ИМХО BerkleyDB базы всё-таки практичнее при большом количестве
> сообщений.
>
Можно использовать несколько файлов для иерархического разделения. Держать все в одном месте неправильно ИМХО, даже если БД справляется. Сначала искать в mySuperFormErrors, потом в mySuperModuleErrors, потом в commonErrors, потом в errors. Таким образом можно перекрыть file.not.found.error для некоторого модуля/формы.
← →
ProgRAMmer Dimonych © (2012-06-27 20:51) [35]> [31] Дмитрий С © (27.06.12 13:11)
> > Может, человек на PHP каком-нибудь работает...
> Вот-вот. В нем и finally нет, реализация функций убогая
> (для скриптового языка)
finally, если очень нужно, можно переписать на catch"ах. Специфика PHP, IMHO, в нескольких вещах:
1. Освобождение памяти автоматическое, finally в большинстве случаев как бы и не нужен.
2. Если исключение произошло - это либо пользовательское исключение, либо признак логической ошибки в скрипте.
2.1. Если программист сам его бросил - значит, где-то сверху он его должен ждать и это будет именно catch (возможно, с последующим throw).
2.2. Если программист исключения не ждёт - значит, он не учитывает какой-то ситуации => анализ задачи выполнен не полностью => скрипт нужно допиливать.
2.3. В обоих случаях пользователя достаточно просто уведомить, что что-то пошло не так. Реализовывать многоуровневую логику обработки исключения по finally просто неактуально.
← →
ProgRAMmer Dimonych © (2012-06-27 20:51) [36]P.S. Хотелось бы подробнее про убогость функций, но оффтоп :)
← →
Владислав © (2012-06-27 22:32) [37]За 10-летнюю практику ни разу не возникла необходимость выбирать из первого или второго варианта. Когда появляется желание выбрать, я переписываю код.
«P.S. Вариант "Не писать такие большие функции" не предлагать. Иногда надо.»
Как раз этот вариант и предлагаю. В 99,99 % это вариант сделать более понятный и простой код.
← →
Rouse_ © (2012-06-27 23:17) [38]С учетом что нет SEH, второй более читабелен, более того еще читабельней станет, если goto на return заменить c финализацией
← →
zzz (2012-06-28 05:32) [39]Не согласен, что для паскаля goto это нонсенс. Да! не нужно им злоуотреблять. Но тем неменее иногда для удочитаемости и реализации легче сделать goto, чем городить "пирамиду" из фиг знает чего.
Это к посту где-то сверху...
← →
Дмитрий С © (2012-06-28 16:04) [40]было бы здорово, если бы из try finally можно было выйти с помощью break. Чтобы смысл был примерно такой:
try
repeat
until true;
finally
...
> P.S. Хотелось бы подробнее про убогость функций, но оффтоп
> :)
В общем то это касается невозможностью перекрывать ранее определенные функции. Отсутствием локальных функций (все функции глобальные). Область видимости для функций продумана через одно место. Последнее время за это дело основательно взялись, но наследие все равно дает о себе знать.
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.181 c