-
Лучше не писать программу так, чтобы поддерживать ее могли только профессионалы с опасными мощными предметами :) Такое мое скромное мнение.
-
"В абсолют возводят только юноши. Жизнь она не только черная или белая она имеет оттенки серого."
верно как по поводу goto, так и по поводу функций по 15 строк
-
-
> Юрий Зотов © (26.05.16 12:00) [77]
> goto поможет всегда.
Кроме попытки выйти из блока try...finally путем перехода на метку как в [65]. Не компилируется даже.
-
> DVM © (26.05.16 13:10) [83] > Кроме попытки выйти из блока try...finally путем перехода > на метку как в [65].
Очень удачны бывают переходы в тело цикла Dо, особенно из других модулей. Хотя трансляторы, как правило, это запрещают, их легко можно обвести вокруг пальца, пользуясь переменными типа метки. Передача управления в вызываемую процедуру в обход заголовка принесет вам долгие часы счастливых раздумий над кодом завершения 0хС5.
-
Rouse_ © (26.05.16 13:13) [84]
:-D
Хорошо сказано. :)
-
> Владислав © (26.05.16 12:09) [78]
> Запускаем, и... Работает неправильно. Почему???
Потому что при вставке нового кода программист не посмотрел двумя строчками выше и не увидел, что третий параметр - двойка.
> Чтобы на такие грабли не наступить, достаточно > не использовать такие операторы.
А с этим никто и не спорит. Конечно, лучше всего их не использовать. Речь лишь о том, что при ГРАМОТНОМ использовании они и безопасны, и позволяют упростить код, и читабельность не ухудшают.
> Rouse_ © (26.05.16 13:13) [84]
Саш, ну ты знаешь что будет, если дураку дать в руки некий стеклянный предмет... :o)
-
Вообще, следуя логике супербезопасности, надо запретить указатели и работу с памятью. А также приведение типов, каскадное удаление в БД - и пр., и пр.
-
Ну так да. Где-то в эту сторону языки программирования и развиваются в основном. Больше типизации, меньше прямой работы с памятью. И это хорошо. Прямой доступ к памяти все равно не нужен почти никогда, а типизация чем строже, тем лучше.
Я помню когда на Coursera курс проходил про языки программирования. Там был частности ML. Так вот отдельные люди с ненавистью о нем писали. Они не могли заставить простейшие программы из 30 строк работать. Угадайте почему? Из-за строгой статической типизации.
Представляете какие программы эти люди на своих php пишут, если у них концепция статической типизации в голове не помещается?
Ограничение себя - статическая типизация, отказ от всяких goto и хаков с памятью - это что-то близкое к восточной философии. Это трудно и есть соблазн сдаться. Но если у тебя в итоге программа хотя бы запустилась, то скорее всего она будет работать :)
-
> Юрий Зотов © (26.05.16 14:40) [87]"Вообще, следуя логике супербезопасности, надо запретить указатели и работу с памятью. А также приведение типов, каскадное удаление в БД - и пр., и пр."К такой логике вроде никто не призывал. По моему мнению, запрещать не нужно, но если можно без этого обойтись, то нужно обойтись. А так можно дойти до подобного: PPersonRec = ^TPersonRec;
TPersonRec = record
FirstName: string;
LastName: string;
end;
...
New(PersonRec);
...
Dispose(PersonRec); Попробуйте переписать этот код с помощью классов, сравним удобство и читабельность. TPerson = class
strict private
FFirstName: string;
FLastName: string;
public
property FirstName: string read FFirstName write FFirstName;
property LastName: string read FLastName write FLastName;
end;
...
Person := TPerson.Create;
...
Person.Free; Ну вот. На три строки больше, писанины больше. Зачем тогда класс, если конструктор, деструктор, геттеры и сеттеры не используются? ;)
-
> Владислав © (26.05.16 15:13) [89]
Опять не тот тег использовал.
PPersonRec = ^TPersonRec; TPersonRec = record FirstName: string; LastName: string; end;
...
New(PersonRec); ... Dispose(PersonRec);
TPerson = class strict private FFirstName: string; FLastName: string; public property FirstName: string read FFirstName write FFirstName; property LastName: string read FLastName write FLastName; end;
...
Person := TPerson.Create; ... Person.Free;
-
> Зачем тогда класс, если конструктор, деструктор, геттеры > и сеттеры не используются? ;)
Ну к примеру если у нас есть некое:
TFoo = class FPerson: array of TPerson; public property Person[Index: Integer]: TPerson read GetPerson write SetPerson; end;
то мы сможем менять любое поле каждой записи TPerson (т.к. объект).
TFoo.Person[0].FirstName := 'qwe';
А если это будет TPersonRec то менять мы сможем только запись целиком, т.е.
Tmp := TFoo.Person[0]; Tmp.FirstName := 'qwe'; TFoo.Person[0] := Tmp;
Ну либо придется переписать структуру вот таким образом:
PPersonRec = ^TPersonRec; TPersonRec = record private FFirstName: string; FLastName: string; public FirstName: string read FFirstName write FFirstName; LastName: string read FLastName write FLastName; end;
TFoo = class FPerson: array of TPersonRec; public property Person[Index: Integer]: TPersonRec read GetPerson write SetPerson; end
-
> [69] Dimka Maslov © (26.05.16 09:31) > Break(2)
Не, ну ты вложишь когда-нибудь потом ещё один цикл, и будет тебе брик 2 не в туда. Тогда уж надо изобрести метку на именованный цикл, но ведь это раздувание семантики языка. А ради чего.
-
> [71] Dimka Maslov © (26.05.16 11:03) > В таких языках, как C++, где break ещё из switch выводит > - вообще была бы песня
Вот не надо гнать на Си++, как раз в нём - с этими метками всё нормально.
-
> [71] Dimka Maslov © (26.05.16 11:03) > Вот такая конструкция у меня прекрасно работает без побочных > эффектов > > #func check(i, j) > #if (i == 2) & (j == 2) then break(2) > #endfunc > > #for i = 1 to 5 > #for j = 1 to 5 > #check(i, j) > #next > #next > > Давайте попробуем повторить такое же в Delphi... Даже goto > не поможет И не надо говорить, что у break для нескольких > циклов возможностей меньше.
Не сомневаюсь. Но мне пришлось в эту конструкцию втыкнуть не с первого раза: как это - левая функция может вывести из цикла? А вдруг она не курит, а вдруг она не пьёт? (Функция - в смысле) А мы стакими рожами возьмём, да и припрёмся к функшен. Не, для меня это не очень привычно. Ну иногда можно, но ту как раз гоуту подойдёт.
-
> Kerk © (26.05.16 15:00) [88]
> Там был частности ML. Так вот отдельные люди > с ненавистью о нем писали
На Паскаль я пересел с PL/1. А этот самый PL/1 вытворял чудеса. Приведение логически несовместимых типов - автоматически, например, Число = Строка (из строки берутся первые байты в количестве размера числа, и эти байты засылаются в число). Вход в цикл минуя его заголовок - запросто. Ну и т.п.
И после этой свободы - Паскаль с его строгой типизацией, представляешь? Я матерился, как шкипер пиратов. Но недолго - потому что быстро понял, как это здорово, когда компилятор страхует от потенциальных ошибок.
Я уже приводил такой пример, приведу его еще раз:
DECLARE I DECIMAL FIXED(1); // На Паскале это var I: 0..9; DO I=0 TO 9 ... // На Паскале это for I := 0 to 9 do...
Запускаем. Программа зацикливается. Ловил 3 дня. А на Паскале сразу получил бы выход за диапазон.
-
Извиняюсь, придётся немного отложить обсуждение с моей стороны - ненадолго.
-
> Юрий Зотов © (26.05.16 19:01) [95]
"А на Паскале сразу получил бы выход за диапазон."
С чего бы? Или в примере очепятка?
-
> Владислав © (26.05.16 19:23) [97]
После последнего прохода цикла (при I=9) идет инкремент I - и получаем Range Check Error. Конечно, если этот контроль включен (а при разработке он у меня включен всегда).
-
> Юрий Зотов © (26.05.16 19:29) [98]
Можно пример, в котором это поведение проявляется?
|