Конференция "Прочее" » Как вы относитесь к использованию меток в Delphi?
 
  • Kerk © (26.05.16 12:33) [80]
    Лучше не писать программу так, чтобы поддерживать ее могли только  профессионалы с опасными мощными предметами :)
    Такое мое скромное мнение.
  • Дмитрий Белькевич © (26.05.16 12:56) [81]
    "В абсолют возводят только юноши. Жизнь она не только черная или белая она имеет оттенки серого."

    верно как по поводу goto, так и по поводу функций по 15 строк
  • Rouse_ © (26.05.16 13:07) [82]
    Оп чем спор?
    Вот почитайте что об этом пишет Дейкстра.
    http://hosting.vspu.ac.ru/~chul/dijkstra/goto/goto.htm
  • DVM © (26.05.16 13:10) [83]

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


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

    Кроме попытки выйти из блока try...finally путем перехода на метку как в [65]. Не компилируется даже.
  • Rouse_ © (26.05.16 13:13) [84]

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

     Очень удачны бывают переходы в тело  цикла  Dо,  особенно  из  других
     модулей. Хотя трансляторы, как правило,  это  запрещают,  их  легко  можно
     обвести  вокруг  пальца,  пользуясь  переменными  типа   метки.   Передача
     управления в вызываемую процедуру в обход заголовка  принесет  вам  долгие
     часы счастливых раздумий над кодом завершения 0хС5.
  • Владислав © (26.05.16 13:32) [85]
    Rouse_ ©   (26.05.16 13:13) [84]

    :-D

    Хорошо сказано. :)
  • Юрий Зотов © (26.05.16 14:35) [86]
    > Владислав ©   (26.05.16 12:09) [78]

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

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

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

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

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

    Саш, ну ты знаешь что будет, если дураку дать в руки некий стеклянный предмет...
    :o)
  • Юрий Зотов © (26.05.16 14:40) [87]
    Вообще, следуя логике супербезопасности, надо запретить указатели и работу с памятью. А также приведение типов, каскадное удаление в БД - и пр., и пр.
  • Kerk © (26.05.16 15:00) [88]
    Ну так да. Где-то в эту сторону языки программирования и развиваются в основном. Больше типизации, меньше прямой работы с памятью. И это хорошо. Прямой доступ к памяти все равно не нужен почти никогда, а типизация чем строже, тем лучше.

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

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

    Ограничение себя - статическая типизация, отказ от всяких goto и хаков с памятью - это что-то близкое к восточной философии. Это трудно и есть соблазн сдаться. Но если у тебя в итоге программа хотя бы запустилась, то скорее всего она будет работать :)
  • Владислав © (26.05.16 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;



    Ну вот. На три строки больше, писанины больше.
    Зачем тогда класс, если конструктор, деструктор, геттеры и сеттеры не используются? ;)
  • Владислав © (26.05.16 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_ © (26.05.16 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 © (26.05.16 18:27) [92]
    > [69] Dimka Maslov ©   (26.05.16 09:31)
    > Break(2)

    Не, ну ты вложишь когда-нибудь потом ещё один цикл, и будет тебе брик 2 не в туда. Тогда уж надо изобрести метку на именованный цикл, но ведь это раздувание семантики языка. А ради чего.
  • Inovet © (26.05.16 18:30) [93]
    > [71] Dimka Maslov ©   (26.05.16 11:03)
    > В таких языках, как C++, где break ещё из switch выводит
    > - вообще была бы песня

    Вот не надо гнать на Си++, как раз в нём - с этими метками всё нормально.
  • Inovet © (26.05.16 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 для нескольких
    > циклов возможностей меньше.

    Не сомневаюсь. Но мне пришлось в эту конструкцию втыкнуть не с первого раза: как это - левая функция может вывести из цикла? А вдруг она не курит, а вдруг она не пьёт? (Функция - в смысле) А мы стакими рожами возьмём, да и припрёмся к функшен. Не, для меня это не очень привычно. Ну иногда можно, но ту как раз гоуту подойдёт.
  • Юрий Зотов © (26.05.16 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 © (26.05.16 19:09) [96]
    Извиняюсь, придётся немного отложить обсуждение с моей стороны - ненадолго.
  • Владислав © (26.05.16 19:23) [97]
    > Юрий Зотов ©   (26.05.16 19:01) [95]

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

    С чего бы? Или в примере очепятка?
  • Юрий Зотов © (26.05.16 19:29) [98]
    > Владислав ©   (26.05.16 19:23) [97]

    После последнего прохода цикла (при I=9) идет инкремент I - и получаем Range Check Error. Конечно, если этот контроль включен (а при разработке он у меня включен всегда).
  • Владислав © (26.05.16 19:40) [99]
    > Юрий Зотов ©   (26.05.16 19:29) [98]

    Можно пример, в котором это поведение проявляется?
 
Конференция "Прочее" » Как вы относитесь к использованию меток в Delphi?
Есть новые Нет новых   [134432   +19][b:0.001][p:0.001]