Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2017.08.13;
Скачать: CL | DM;

Вниз

Как вы относитесь к использованию меток в Delphi?   Найти похожие ветки 

 
Kerk ©   (2016-05-26 12:33) [80]

Лучше не писать программу так, чтобы поддерживать ее могли только  профессионалы с опасными мощными предметами :)
Такое мое скромное мнение.


 
Дмитрий Белькевич ©   (2016-05-26 12:56) [81]

"В абсолют возводят только юноши. Жизнь она не только черная или белая она имеет оттенки серого."

верно как по поводу goto, так и по поводу функций по 15 строк


 
Rouse_ ©   (2016-05-26 13:07) [82]

Оп чем спор?
Вот почитайте что об этом пишет Дейкстра.
http://hosting.vspu.ac.ru/~chul/dijkstra/goto/goto.htm


 
DVM ©   (2016-05-26 13:10) [83]


> Юрий Зотов ©   (26.05.16 12:00) [77]


> goto поможет всегда.

Кроме попытки выйти из блока try...finally путем перехода на метку как в [65]. Не компилируется даже.


 
Rouse_ ©   (2016-05-26 13:13) [84]


> DVM ©   (26.05.16 13:10) [83]
> Кроме попытки выйти из блока try...finally путем перехода
> на метку как в [65].

 Очень удачны бывают переходы в тело  цикла  Dо,  особенно  из  других
 модулей. Хотя трансляторы, как правило,  это  запрещают,  их  легко  можно
 обвести  вокруг  пальца,  пользуясь  переменными  типа   метки.   Передача
 управления в вызываемую процедуру в обход заголовка  принесет  вам  долгие
 часы счастливых раздумий над кодом завершения 0хС5.


 
Владислав ©   (2016-05-26 13:32) [85]

Rouse_ ©   (26.05.16 13:13) [84]

:-D

Хорошо сказано. :)


 
Юрий Зотов ©   (2016-05-26 14:35) [86]

> Владислав ©   (26.05.16 12:09) [78]

> Запускаем, и... Работает неправильно. Почему???

Потому что при вставке нового кода программист не посмотрел двумя строчками выше и не увидел, что третий параметр - двойка.

> Чтобы на такие грабли не наступить, достаточно
> не использовать такие операторы.

А с этим никто и не спорит. Конечно, лучше всего их не использовать. Речь лишь о том, что при ГРАМОТНОМ использовании они и безопасны, и позволяют упростить код, и читабельность не ухудшают.

> Rouse_ ©   (26.05.16 13:13) [84]

Саш, ну ты знаешь что будет, если дураку дать в руки некий стеклянный предмет...
:o)


 
Юрий Зотов ©   (2016-05-26 14:40) [87]

Вообще, следуя логике супербезопасности, надо запретить указатели и работу с памятью. А также приведение типов, каскадное удаление в БД - и пр., и пр.


 
Kerk ©   (2016-05-26 15:00) [88]

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

Я помню когда на Coursera курс проходил про языки программирования. Там был частности ML. Так вот отдельные люди с ненавистью о нем писали. Они не могли заставить простейшие программы из 30 строк работать. Угадайте почему? Из-за строгой статической типизации.

Представляете какие программы эти люди на своих php пишут, если у них концепция статической типизации в голове не помещается?

Ограничение себя - статическая типизация, отказ от всяких goto и хаков с памятью - это что-то близкое к восточной философии. Это трудно и есть соблазн сдаться. Но если у тебя в итоге программа хотя бы запустилась, то скорее всего она будет работать :)


 
Владислав ©   (2016-05-26 15:13) [89]

> Юрий Зотов ©   (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;


Ну вот. На три строки больше, писанины больше.
Зачем тогда класс, если конструктор, деструктор, геттеры и сеттеры не используются? ;)


 
Владислав ©   (2016-05-26 15:15) [90]

> Владислав ©   (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;


 
Rouse_ ©   (2016-05-26 16:03) [91]


> Зачем тогда класс, если конструктор, деструктор, геттеры
> и сеттеры не используются? ;)

Ну к примеру если у нас есть некое:

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


 
Inovet ©   (2016-05-26 18:27) [92]

> [69] Dimka Maslov ©   (26.05.16 09:31)
> Break(2)

Не, ну ты вложишь когда-нибудь потом ещё один цикл, и будет тебе брик 2 не в туда. Тогда уж надо изобрести метку на именованный цикл, но ведь это раздувание семантики языка. А ради чего.


 
Inovet ©   (2016-05-26 18:30) [93]

> [71] Dimka Maslov ©   (26.05.16 11:03)
> В таких языках, как C++, где break ещё из switch выводит
> - вообще была бы песня

Вот не надо гнать на Си++, как раз в нём - с этими метками всё нормально.


 
Inovet ©   (2016-05-26 18:38) [94]

> [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 для нескольких
> циклов возможностей меньше.

Не сомневаюсь. Но мне пришлось в эту конструкцию втыкнуть не с первого раза: как это - левая функция может вывести из цикла? А вдруг она не курит, а вдруг она не пьёт? (Функция - в смысле) А мы стакими рожами возьмём, да и припрёмся к функшен. Не, для меня это не очень привычно. Ну иногда можно, но ту как раз гоуту подойдёт.


 
Юрий Зотов ©   (2016-05-26 19:01) [95]

> 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 дня. А на Паскале сразу получил бы выход за диапазон.


 
Inovet ©   (2016-05-26 19:09) [96]

Извиняюсь, придётся немного отложить обсуждение с моей стороны - ненадолго.


 
Владислав ©   (2016-05-26 19:23) [97]

> Юрий Зотов ©   (26.05.16 19:01) [95]

"А на Паскале сразу получил бы выход за диапазон."

С чего бы? Или в примере очепятка?


 
Юрий Зотов ©   (2016-05-26 19:29) [98]

> Владислав ©   (26.05.16 19:23) [97]

После последнего прохода цикла (при I=9) идет инкремент I - и получаем Range Check Error. Конечно, если этот контроль включен (а при разработке он у меня включен всегда).


 
Владислав ©   (2016-05-26 19:40) [99]

> Юрий Зотов ©   (26.05.16 19:29) [98]

Можно пример, в котором это поведение проявляется?


 
Kerk ©   (2016-05-26 19:48) [100]

Я тоже честно говоря не понял конкретный пример. Но идея понятна.


 
Владислав ©   (2016-05-26 20:00) [101]

> Kerk ©   (26.05.16 19:48) [100]

Идея-то понятно, но если бы был Range Check Error с переменной цикла, это был бы большой фейл.

var
 I: 0..9;
begin
 for I := 0 to 9 do // Нет выхода за границы диапазона, не будет и исключения.
   ;
end;


 
Юрий Зотов ©   (2016-05-26 20:05) [102]

А ведь и верно - в Delphi ошибки нет. Но в Turbo Pascal 5.5 точно была.


 
Плохиш ©   (2016-05-26 20:17) [103]

Читал ветку, читал. Но так и не понял, о чём копья ломаются.
Господа, какую проблему решаем?


 
Sha ©   (2016-05-26 20:20) [104]

> Юрий Зотов ©   (26.05.16 19:01) [95]
> Вход в цикл минуя его заголовок - запросто.

Это в PL как раз нельзя было.
Если, конечно, память не обманывает.


 
Inovet ©   (2016-05-26 21:36) [105]

Так, начиная с [72] - всё быстро просмотрел, местами даже относительно внимательно. Похоже, пока что, добавить мне нечего.

ПС. А кто это там так боянисто вбросил? И зачем? - вот главный вопрос.:) А вы тут про метки и прочие агрегаты.:)
Если что - я тут уже давно под одним ником.


 
Юрий Зотов ©   (2016-05-26 22:07) [106]

> Плохиш ©   (26.05.16 20:17) [103]

> Читал ветку, читал. Но так и не понял, о чём копья ломаются.
> Господа, какую проблему решаем?


А никакую, просто общаемся. Редкий случай, когда разговор на холиварную тему протекает в нормальном тоне.


 
DayGaykin ©   (2016-05-26 22:16) [107]


> Kerk ©   (26.05.16 15:00) [88]
> Ну так да. Где-то в эту сторону языки программирования и
> развиваются в основном. Больше типизации, меньше прямой
> работы с памятью. И это хорошо

Насчет типизации соглашусь. Насчет работы с памятью: сборщики мусора, по-моему, зло злейшее. Жаль что эта мода врядли скоро пройдет. Думаю можно найти приемлемый способ убивать ненужные объекты сразу после выхода из зоны видимости и не использовать сборщик мусора.


 
Юрий Зотов ©   (2016-05-26 22:51) [108]

> DayGaykin ©   (26.05.16 22:16) [107]

> можно найти приемлемый способ убивать
> ненужные объекты сразу после выхода из зоны видимости и
> не использовать сборщик мусора.


Его и искать не надо, он уже есть: обнулился счетчик ссылок - убили объект.

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


 
Юрий Зотов ©   (2016-05-26 23:09) [109]

Кстати, интересная штука открылась (в java). Есть там метод freeMemory, который, если верить документации, просто возвращает кол-во свободной памяти в байтах. И был у меня кусок программы, который загружал дисковый файл и по нему строил в памяти список неких объектов.

Так вот - если этот файл слишком большой, то возникало то самое OutOfMemory. Тогда при отладке перед и после этого куска я вставил freeMemory с выводом в консоль - для контроля.

Ошибка тут же исчезла. Предполагаю (хотя в документации это не сказано), что внутри freeMemory сначала происходит принудительная сборка мусора и дефрагментация памяти, а уж потом возвращается ее количество.

Позже я использовал этот прием и в других похожих местах. Результат всегда был один - ошибка OutOfMemory исчезала.


 
Kerk ©   (2016-05-27 00:41) [110]

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


 
Германн ©   (2016-05-27 01:10) [111]


> Юрий Зотов ©   (26.05.16 20:05) [102]
>
> А ведь и верно - в Delphi ошибки нет. Но в Turbo Pascal
> 5.5 точно была.
>

Юр, не было. TP 5.5 у меня под рукой. До сих пор использую. Пришлось даже VMWare установить.
Точнее, если и была, то не в совсем таком коде. Да после итерации счетчик цикла сначала увеличивается, а затем проверяется условие цикла. Но это не должно приводить к ошибке.


 
Юрий Зотов ©   (2016-05-27 05:07) [112]

> Германн ©   (27.05.16 01:10) [111]

Поставь опции (или птички):
{R+}
{Q+}
{O-}
и сбилди проект.


 
Eraser ©   (2016-05-27 08:37) [113]


> Kerk ©   (27.05.16 00:41) [110]
> Фатальный недостаток счетчика ссылок - циклические ссылки.
>

ну в новой версии сделали weak reference, правда это само по себе несколько портит концепцию подсчета ссылок.


 
Kerk ©   (2016-05-27 11:43) [114]

Да, это самая важная фича со времен дженериков по-моему :)


 
K-1000 ©   (2016-05-27 20:46) [115]

Самое интересное, что в "Модула-2" GOTO убрали. :)


 
jack128 ©   (2016-05-29 01:04) [116]


> А если это будет TPersonRec то менять мы сможем только запись
> целиком, т.е.

Это следствие дизайна дельфи, который гласит: "за любое удобство нужно платить производительностью".
В плюсах, и кстати в следующей версии C#, то что ты хочешь можно и для структур со свойствами сделать.


 
Германн ©   (2016-05-29 02:22) [117]


> Юрий Зотов ©   (27.05.16 05:07) [112]
>
> > Германн ©   (27.05.16 01:10) [111]
>
> Поставь опции (или птички):
> {R+}
> {Q+}
> {O-}
> и сбилди проект.
>

Юр. Поставил/снял птички/галочки R и O и сбилдил проект. Птичку/галочку Q не нашел в Options. Поставил в коде явно.
{Q+}
program Test;
var i : 0..9;

begin
 for i:=0 to 9 do
end.

Никаких сообщений об ошибках не получил.


 
Германн ©   (2016-05-29 02:24) [118]

Ну т.е. {$Q+}.


 
DVM ©   (2016-05-29 11:48) [119]


> Юрий Зотов ©   (26.05.16 23:09) [109]


> Результат всегда был один - ошибка OutOfMemory исчезала.

Мне кажется, если в программе возникает OutOfMemory - это повод задуматься об алгоритмах и архитектуре программы, а не добавлять недокументированные костыли.
Может я конечно не прав и в мире Java все не так.


 
Юрий Зотов ©   (2016-05-29 12:34) [120]

> DVM ©   (29.05.16 11:48) [119]

> Мне кажется, если в программе возникает OutOfMemory - это
> повод задуматься об алгоритмах и архитектуре программы,
> а не добавлять недокументированные костыли.
> Может я конечно не прав и в мире Java все не так.


Прав, естественно. Только ошибку сначала надо локализовать, не так ли?



Страницы: 1 2 3 4 вся ветка

Текущий архив: 2017.08.13;
Скачать: CL | DM;

Наверх




Память: 0.71 MB
Время: 0.009 c
2-1427136740
NovichoK2
2015-03-23 21:52
2017.08.13
освобождение строковых параметров класса


15-1463757911
SergP
2016-05-20 18:25
2017.08.13
Как вы относитесь к использованию меток в Delphi?


2-1422502870
Drowsy
2015-01-29 06:41
2017.08.13
Вычисляемые поля ДатаСета.


2-1426513998
dmk
2015-03-16 16:53
2017.08.13
Возможно ли имея имя класса в переменной обратится


2-1443091187
Andrey K
2015-09-24 13:39
2017.08.13
Как заблокировать клавишу?