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

Вниз

Трюки в Delphi   Найти похожие ветки 

 
Виктор1985   (2014-04-22 13:11) [0]

Приветствую! Наткнулся сегодня на статью
http://wiert.me/2014/04/21/today-i-learned-i-didnt-know-about-this-syntax-for-properties-via-roman-yankovsky-google/

Собственно захотелось узнать, может у кого в загашнике есть своя порция интересных трюков?

От себя:

Получение смещения поля в структуре

//Получение смещения поля TypeInfo в структуре типа PackageInfoTable
LongWord(@PackageInfoTable(nil^).TypeInfo))


 
Игорь Шевченко ©   (2014-04-22 13:25) [1]

There is no limit to how bad things can get :)


 
Kerk ©   (2014-04-22 13:37) [2]

Вот тут еще подборка редко используемых возможностей
http://delphi.org/2014/02/hidden-features-in-the-delphi-object-pascal-language/


 
Виктор1985   (2014-04-22 14:03) [3]

Вот еще вспомнил, понадобилось обратиться к байтам LongWord"a, как то затупил и начал сдвиги применять, маски... не сразу вспомнил про приведение типов, а когда вспомнил переписал и вышло очень читабельно:


type
 B32 = array[1..4] of Byte;
..
var
 T0: LongWord;

B32(T0)[1] //читаем первый байт
B32(T0)[2] //читаем второй байт


 
Дмитрий СС   (2014-04-22 14:55) [4]

Вот бы придумали способ обнулять локальные переменные автоматически. Хотя бы объектовые только.


 
junglecat   (2014-04-22 15:20) [5]

> обнулять локальные переменные автоматически

а нафига?


 
Dimka Maslov ©   (2014-04-22 15:56) [6]


> Kerk ©   (22.04.14 13:37) [2]


Такое ощущение, что список составляли ламеры-батонокидатели, которые внезапно что-то где умудрились прочитать...


 
sniknik ©   (2014-04-22 16:01) [7]

> обнулять локальные переменные автоматически. Хотя бы объектовые только.
интерфейсы. пользуйтесь интерфейсами.


 
Ega23 ©   (2014-04-22 16:04) [8]


> Вот бы придумали способ обнулять локальные переменные автоматически.


Не обнулять, а приводить к начальному состоянию. Что далеко не всегда 0 или nil


 
junglecat   (2014-04-22 16:09) [9]

> приводить к начальному состоянию

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


 
Виктор1985   (2014-04-22 16:13) [10]

> приводить к начальному состоянию

возможность задавать как для глобальных переменных, типа
var
 Node: TNode = nil;
begin
 //...

приводило бы к тому что бы код превращался в

var
 Node: TNode;
begin
 Node := nil;
 //...


 
Виктор1985   (2014-04-22 16:20) [11]

Вот еще, недавно наткнулся. Возможность включать изменения констант. По сути такая константа является глобальной переменной доступной только в области видимости используемой функции. Вот пример:

procedure MaxOrNormalForm(AForm: TForm; AMax: Boolean);
const
{$J+}
 LastBounds: TRect = ();
{$J-}
begin
 if AMax then
 begin
   LastBounds := AForm.BoundsRect;
   AForm.FormStyle := fsStayOnTop;
   AForm.BorderStyle := bsNone;
   AForm.BoundsRect := Screen.MonitorFromWindow(AForm.Handle).BoundsRect;
 end
 else
 begin
   AForm.FormStyle := fsNormal;
   AForm.BorderStyle := bsSizeable;
   AForm.BoundsRect := LastBounds;
 end;
end;


 
Ega23 ©   (2014-04-22 16:29) [12]


>  Возможность включать изменения констант.


Гхм... Это ещё в турбопаскале пятом было. Называлось "типизированная константа".


 
Германн ©   (2014-04-22 16:49) [13]


> Ega23 ©   (22.04.14 16:29) [12]
>
>
> >  Возможность включать изменения констант.
>
>
> Гхм... Это ещё в турбопаскале пятом было. Называлось "типизированная
> константа".
>  

На самом деле это возможность вЫключать изменения констант. Чего в ТР5 не было :)


 
Дмитрий СС   (2014-04-23 00:59) [14]


> а нафига?

К примеру, в методе используется два стринглиста и один стрим. По идее три вложенных try finally, но можно и так:
Sl1:=nil;
Sl2:=nil;
MS:=nil;
Try
Sl1:=Tstringlist.create;
Sl2:=Tstringlist.create;
MS:=Tmemorystream.create;
...
Finally
Sl1.free;
Sl2.free;
Ms.free;
End;

Плюсов у этого подхода полно, но утоляет обниливание писать. Хотя есть идея:
Var
 LM:IMyLocalManager;

LM:=TMyLocalManager.Create([@Sl1, @Sl2, @MS]);
Дальше создаём, удаляем или не удаляем. Если что LM при освобождении сам все удалит))


 
Ega23 ©   (2014-04-23 07:44) [15]


> Плюсов у этого подхода полно

В данном примере нет ни одного плюса. А вот минусов - таки полно.


 
junglecat   (2014-04-23 08:38) [16]

> Плюсов у этого подхода полно

не видно ни одного.
почему create должно быть внутри try?


 
KilkennyCat ©   (2014-04-23 09:04) [17]

некоторые трюки могут дорого обойтись после компиляции. надеюсь, там после каждого трюка написано что-нить типа: сокращает ресурсы на 5% ускоряет на 10% и дает +5% к уверенности?


 
junglecat   (2014-04-23 09:29) [18]

> и дает +5% к уверенности?

и +20 к карме


 
brother ©   (2014-04-23 09:42) [19]

+5 к магии - 30 к понятности и стабильности кода...


 
Palladin ©   (2014-04-23 10:28) [20]


> Дмитрий СС   (23.04.14 00:59) [14]

очень глупое решение

Finally
Sl1.free; // бац эксцепш
Sl2.free; // лик
Ms.free; // лик
End;

а че там про плюсы то? а то, кроме упоминания, что они есть больше ничего и нет


 
имя   (2014-04-23 10:32) [21]

Удалено модератором


 
Rouse_ ©   (2014-04-23 19:41) [22]


> Плюсов у этого подхода полно

Огласите весь список, пожалуйста… ©


 
Дмитрий СС   (2014-04-24 04:21) [23]


> очень глупое решение

Если у вас ексепшн на освобождении простого стандартного класса, то скорее всего уже чтото сильно пошло не так.

Плюс, самый главный в том, что не нужно городить большое количество Try finally.
+ Проще выбирать момент создания и смерти объекта (freeandnil).

Впрочем, бесполезно что-либо объяснять. В соседней ветке решили сложную алгоритмическую задачу, а тут понять не могут, почему создание объекта внутри try.


 
Ega23 ©   (2014-04-24 07:51) [24]


> что не нужно городить большое количество Try finally.


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


 
jack128_   (2014-04-24 10:18) [25]


> > что не нужно городить большое количество Try finally.
>
>
> Зато придётся писать большое количество FreeAndNil, либо
> обниливать все локальные переменные в самом начале.
> Надеюсь, не надо объяснять, почему?


если использовать вложенные try finally, то для создания/уничтожения N объектов нам понадобится 5*N строк кода. Для метода Дмитрий СС понадобится 3 + 3*N строк кода. То есть уже для двух объектов уже короче как Дима писать.


> очень глупое решение
>
> Finally
> Sl1.free; // бац эксцепш
> Sl2.free; // лик
> Ms.free; // лик
> End;

Ты так говоришь, как будто если б ты написал вложенные try finally, то мем лика бы не было :-D


 
Игорь Шевченко ©   (2014-04-24 10:28) [26]

jack128_   (24.04.14 10:18) [25]

Писать надо не коротко, а понятно.


 
Ega23 ©   (2014-04-24 10:39) [27]


> если использовать вложенные try finally, то для создания/уничтожения
> N объектов нам понадобится 5*N строк кода. Для метода Дмитрий
> СС понадобится 3 + 3*N строк кода. То есть уже для двух
> объектов уже короче как Дима писать.


code template сам все finally вставит, с end-ом и отступами.
А так всё ручкаме придётся писать.


 
Rouse_ ©   (2014-04-24 10:52) [28]


> Плюс, самый главный в том, что не нужно городить большое
> количество Try finally.

А в чем плюс?


> Проще выбирать момент создания и смерти объекта (freeandnil).

А зачем? Темболее есть другие более безопасные методы для этого, даже try..finally писать не нужно будет.


> jack128_   (24.04.14 10:18) [25]

т.е. ты считаешь это правильный подход? :)
Подумай прежде чем ответить, я пока за топорм схожу ;)


 
jack128_   (2014-04-24 11:22) [29]

А код [14] не понятен?


 
Ega23 ©   (2014-04-24 11:34) [30]


> А код [14] не понятен?


Я тебе приватно сказал, теперь публично повторюсь: я на этот код втыкал где-то с минуту, при этом совершенно не обратил внимание на то, что локальные переменные перед try принудительно обниливаются.
ИМХО, это как Destroy вместо Free использовать. В тех самых 95% случаев, когда мы юзаем локальный класс, то особой разницы нет. При разрушении вложенных объектов - тоже нет, если в конструкторе исключение не поднимается.


 
junglecat   (2014-04-24 11:35) [31]

такая интригующая тема намечалась, а свалились в банальный try...)


 
Ega23 ©   (2014-04-24 11:46) [32]

Удалено модератором


 
Rouse_ ©   (2014-04-24 11:55) [33]

Удалено модератором


 
jack128_   (2014-04-24 11:59) [34]


> такая интригующая тема намечалась,

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

unit unti1;
inteface
 procedure DoWork(i: Integer); overload; // в старых дельфях был варнинг, что overload не нужен
...

unit unti2;
inteface
 procedure DoWork(str: string); overload;
...


unit unti3;
uses
 Unit1, Unit2;
...
DoWork(10); // компилируется. А вот если убрать overload хотя с одной функции DoWork - то не компилируется.



 
Владислав ©   (2014-04-24 18:15) [35]

Ega23 ©   (23.04.14 07:44) [15]
"В данном примере нет ни одного плюса. А вот минусов - таки полно."

Огласите весь список, пожалуйста. :)
Сам я обычно так не пишу, но интересно, что же такого плохого в конструкции?


 
Rouse_ ©   (2014-04-24 18:30) [36]


> Владислав ©   (24.04.14 18:15) [35]

1. Это семантически неверная реализация кода, что приводит к затруднению читаемости.
2. Это идеологически неверно выстроенный подход, допускающий наличие утечек памяти в объектов, напрямую не связанными с ошибками.
3. Это делается гораздо проще, на основе смартпойнтеров, не требующих try..finally блоков
4. это затрудняет поиск возникновения ошибки, посредством инструментов наподобие FastMM (в логе которого будет куча неосвобожденных обьектов всвязи с пунктом 2)
5. Человек, настолько уверенный в своей правоте при применении данного подхода давным давно должен вообще отказаться от использовании try..finally, ибо зачем? Если мы являемся профессионалом, то пишем код, такого-же качества, стало быть излишества в виде SEH фреймов для нас лишние, впрочем как и вызовы Free (зачем перестраховываться, ведь мы профессионалы - нужно работать напрямую с Dectroy? :)
6. До кучи, раз уж мы боремся за количество строчек кода в виде 5*N строк кода против 3 + 3*N - нужно как минимум вспомнить что писать можно несколько инструкций в одну строчку. Такой код программы будет очарователен и самое главное будет занимать очень мало строчек, что несомненно является громадным преимуществом :)


 
junglecat   (2014-04-24 18:31) [37]

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

индусы с тобой не согласятся: у них построчная оплата труда


 
Rouse_ ©   (2014-04-24 18:32) [38]


> junglecat   (24.04.14 18:31) [37]
> индусы с тобой не согласятся: у них построчная оплата труда

Ассемблерщики у индусов - олигархи как минимум :)))


 
junglecat   (2014-04-24 18:34) [39]

> Ассемблерщики у индусов

это нонсенс. Они предпочитают VB


 
Rouse_ ©   (2014-04-24 18:36) [40]


> junglecat   (24.04.14 18:34) [39]

Между прочим язык - огонь, только OnErrorGoToNext чего стоит, все try нервно курят в сторонке :)



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

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

Наверх




Память: 0.57 MB
Время: 0.007 c
15-1397751666
KilkennyCat
2014-04-17 20:21
2014.11.30
Как правильно сделать запрос SQL


15-1397723572
й
2014-04-17 12:32
2014.11.30
еще 1 задачка


11-1255323804
Soloton
2009-10-12 09:03
2014.11.30
Способ(ы) передачи сообщений от главного потока к второстепенным


15-1397939403
Юрий
2014-04-20 00:30
2014.11.30
С днем рождения ! 20 апреля 2014 воскресенье


15-1397823673
ВладОшин
2014-04-18 16:21
2014.11.30
напомните, как сплитер динамически поместить правильно