Последнее время я не программирую, а рaзгpебаю зaвалы которые оставили до меня покoления программистов. Чтобы внести минимальное декоративное изменение требуется исправить несколько модулей и потратить несопоставимую по сложности работу по выискиванию всех мест, в которые надо внести изменения.
Дело в том, что тем методы, которые допустимы в примерах, олимпиадах и лабах по программированию, совершенно неприемлемы при создании крупных и долгоживущих прикладных программ.
Предлагаю в этой теме публиковать примеры, как не надо программировать на Delphi, что бы потом не было мучительно больно от встречи с теми, кто исправлял твой код.
Всего в теме 421 сообщение
Добавить свое сообщение
Отслеживать это обсуждение
№ 201 16-05-2008 01:26 | |
Ответ на »сообщение 197« (Cepгей Poщин)
___________________________
А еще более наглдядно -- выносить тексты SQL-запросов из кода в константы и размещать все одним блоком где-то в начале модуля. Удобство, читабельность и простота поддержки еще больше возрастает.
Более того, если у нас есть какие-то одинаковые по струткуре запросы, но к разным таблицам и/или к разным полям, то можно подготовить и вынести в константы шаблон запроса, в который той же функцией Format подставлять перед использованием нужные таблицы и поля. Очень облегчает жизнь.
№ 200 15-05-2008 23:20 | |
Ответ на »сообщение 199« (Бел Амор)
___________________________
Хотелось бы узнать мнение уважаемой публики по поводу использования переменной Result в качестве переменной цикла. В принципе, в VCL этот приём используется достаточно широко.
Очень часто использую именно такой вариант. А что еще делать, если нет оператора return? :-)
№ 199 15-05-2008 17:47 | |
Хотелось бы узнать мнение уважаемой публики по поводу использования переменной Result в качестве переменной цикла. В принципе, в VCL этот приём используется достаточно широко. Но тут есть некоторые нюансы. Например, рассмотрим такой код:
const
Keywords: array [1..3] of String = ('help', 'clear', 'date');
function FindKeyword(Keyword: String): Integer;
begin
for Result := Low(Keywords) to High(Keywords) do
if Keyword = Keywords[Result] then
Exit;
Result := -1;
end; Компилятор на такой код не ругается. Но если убрать после цикла присвоение значения Result, то, кроме того, что это будет неправильно по логике (о чём компилятор не знает), мы получим ещё и предупреждение компилятора:
FOR-Loop variable '%s' may be undefined after loop (W1037)
Из справки по этому предупреждению следует, что:
1. Если цикл завершился сам, то мы должны считать, что значение Result не определено и обязательно должны присвоить ему значение, прежде, чем как-то использовать, в частности, как возвращаемое значение (ну, это как обычно)...
2. Если выход из цикла происходит до его естественного завершения, например, по Exit (упоминаются goto и exit, но почему-то не упомянут break), то значение Result определено и мы вполне можем ему доверять...
P.S. Из справки:
FOR-Loop variable '%s' may be undefined after loop (W1037)
This warning is issued if the value of a for loop control variable is used after the loop.
You can only rely on the final value of a for loop control variable if the loop is left with a goto or exit statement.
The purpose of this restriction is to enable the compiler to generate efficient code for the for loop. program Produce;
function Search(const A: array of Integer; Value: Integer): Integer;
begin
for Result := 0 to High(A) do
if A[Result] = Value then
break;
end;
const
A : array [0..9] of Integer = (1,2,3,4,5,6,7,8,9,10);
begin
Writeln( Search(A,11) );
end. In the example, the Result variable is used implicitly after the loop, but it is undefined if we did not find the value - hence the warning. program Solve;
function Search(const A: array of Integer; Value: Integer): Integer;
begin
for Result := 0 to High(A) do
if A[Result] = Value then
exit;
Result := High(a)+1;
end;
const
A : array [0..9] of Integer = (1,2,3,4,5,6,7,8,9,10);
begin
Writeln( Search(A,11) );
end. The solution is to assign the intended value to the control variable for the case where we don't exit the loop prematurely.
№ 198 14-05-2008 05:52 | |
Ответ на »сообщение 197« (Cepгей Poщин)
___________________________
Вроде мелочь: SQL.Clear;
SQL.Add('SELECT ');
SQL.Add(' Field1,');
SQL.Add(' Field2,');
SQL.Add(' Field3,');
SQL.Add(' Field4');
....
Это не мелочь. Это дублирование кода. Можно написавшего так программиста отправить читать Фаулера, пока не научится распознавать дурно пахнущий код ;-)
№ 197 14-05-2008 05:34 | |
Вроде мелочь: SQL.Clear;
SQL.Add('SELECT ');
SQL.Add(' Field1,');
SQL.Add(' Field2,');
SQL.Add(' Field3,');
SQL.Add(' Field4');
.... но не пишите так. Гораздо более наглядно: SQL.Text := 'SELECT ' + #13#10 +
' Field1,' + #13#10 +
' Field2,' + #13#10 +
' Field3,' + #13#10 +
' Field4 ' ... Во-первых это можно легко преобразовать в текстовую константу, а во-вторых некторые программы, такие как PL/SQL Developper позволяют копировать текст сформированного запроса в таком формате.
№ 196 16-04-2008 02:53 | |
№ 195 15-04-2008 05:52 | |
Ответ на »сообщение 194« (Денис Зайцев)
___________________________
Пардон, имелась в виду функция TextToShortCut.
№ 194 15-04-2008 05:50 | |
Ответ на »сообщение 185« (Geo)
___________________________
>>>>>> Как бы его следовало переписать...
>>>Это элементарно!
repeat
OldShift := Shift;
if CompareFront(Text, MenuKeyCaps[mkcShift]) then Shift := Shift or scShift
else if CompareFront(Text, '^') then Shift := Shift or scCtrl
else if CompareFront(Text, MenuKeyCaps[mkcCtrl]) then Shift := Shift or scCtrl
else if CompareFront(Text, MenuKeyCaps[mkcAlt]) then Shift := Shift or scAlt;
until OldShift = Shift;
А вот и нетушки! Формально данный кусок кода не эквивалентен тому, который заменяет! Это кусок из функции ShortCutToText, который убирает из переданной строки префиксы 'Ctrl+', 'Alt+', 'Shift+', '^' и в соответствии с ними изменяет переменную Shift. Теоретически может случиться, что на вход будут подана строка, например, 'Alt+Alt+Alt+Ins', из которой исходный вариант оставит 'Ins', а Ваш - 'Alt+Ins'.
№ 193 15-04-2008 04:18 | |
Ответ на »сообщение 192« (Geo)
___________________________
Нигде не видел явногол указания на такую направленность Ну там идет упоминание об олимпиадах и лабах по программированию, профессионалы этим обычно не занимаются, хотя всякое бывает.
№ 192 15-04-2008 03:47 | |
Ответ на »сообщение 191« (Cepгей Poщин)
___________________________
>>> Тема-то, по моему разумению в их адрес в основном и направлена.
Нигде не видел явногол указания на такую направленность.
>>> А иначе всегда можно привести примеры оправданного использования и GOTO и CopyPaste.
Чем я и занимаюсь. По моему скромному разумению, в Паскале вообще нет плохих конструкций. То есть таких, применение которых всегда было бы неоправданным. Может быть, и были когда-то, но вымерли в процессе эволюции ;-) Да, есть конструкции, оправданное применение которых встречается в практике крайне редко. Есть конструкции, которые требуют при использовании особой осторожности. И без тех, и без других, в принципе, можно обойтись. Но не обязательно.
Поэтому, когда я вижу слова "всегда" или "никогда", то начинаю психовать :D
Добавить свое сообщение
Отслеживать это обсуждение
Дополнительная навигация: |
|