Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2011.07.31;
Скачать: [xml.tar.bz2];

Вниз

AfterConstruction, beforedestruction у record   Найти похожие ветки 

 
_oxffff   (2011-04-11 09:50) [80]


> Дмитрий С ©   (11.04.11 08:44) [79]
>
> > Нет. Это не инициализатор, и не финализатор.
>
> А что тогда? в чем предназначение?


Это события экземпляра типа, о том что экземпляр аллокировался и о том, что экземпляр разрушается.


 
DiamondShark ©   (2011-04-11 11:04) [81]


> _oxffff   (11.04.11 09:50) [80]

И кому они нужны?


 
oxffff ©   (2011-04-11 12:21) [82]


> DiamondShark ©   (11.04.11 11:04) [81]
>
> > _oxffff   (11.04.11 09:50) [80]
>
> И кому они нужны?


Тебе.


 
DiamondShark ©   (2011-04-11 12:32) [83]


> oxffff ©   (11.04.11 12:21) [82]

Зачем?


 
_oxffff   (2011-04-11 14:10) [84]


> DiamondShark ©   (11.04.11 12:32) [83]
>
> > oxffff ©   (11.04.11 12:21) [82]
>
> Зачем?


Затем.


 
DiamondShark ©   (2011-04-11 14:24) [85]

Содержательно, чо.


 
Mystic ©   (2011-04-11 19:21) [86]

> И кому они нужны?

В основном создание всяких трюков, основанных на неявном гарантированном вызове некоторого кода по выходу из области видимости. Что хорошо при работе со всяким API. Например,


type
 THandle = record
   Value: THandle;
   procedure Initialize();
   procedure Finalize();
 end;

 procedure THandle.Initialize();
 begin
   Value := 0;
 end;

 procedure THandle.Finalize();
 begin
   if (Value <> 0) and (Value <> INVALID_HANDLE_VALUE) then
     CloseHandle(Handle);
 end;


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

А переопределив Adjust мы вообще можем перестать следить и за копированием:


 procedure THandle.Adjust();
 begin
   if Handle = 0 then Exit;

   DuplicateHandle(
     SourceProcessHandle => GetCurrentProcess(),
     SourceHandle => Handle,
     TargetProcessHandle => GetCurrentProcess(),
     TargetHandle => Handle,
     DesiredAccess => 0,
     InheritHandle => False,
     Options => DUPLICATE_SAME_ACCESS
   );
 end;


 
DiamondShark ©   (2011-04-11 20:51) [87]


> Mystic ©   (11.04.11 19:21) [86]

Это очень классный пример, но какую долю кода составляют подобные трюки?
Я предлагал автору провести анализ использования.
Знаете, можно наковырять стопицот "всяких трюков", под которые можно затребовать новую фичу языка.
Стоит ли овчинка выделки, если эти трюки составляют сотую долю процента кода, написанного на этом языке? Ну, допустим, автору ветки по барабану, у него один сам себе разработчик и ноль пользователей. А для сколь-нибудь реального языка?


 
_Юрий   (2011-04-11 21:06) [88]


> DiamondShark ©   (11.04.11 20:51) [87]


> но какую долю кода составляют подобные трюки?


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


 
oxffff ©   (2011-04-11 21:19) [89]


> Я предлагал автору провести анализ использования.


Выше я уже написал о RAII.


> Стоит ли овчинка выделки,


Ну подставить вызовы в цикле по слотам scope при enter scope и leave scope это можно сказать бесплатно.


 
Mystic ©   (2011-04-11 22:05) [90]


> Это очень классный пример, но какую долю кода составляют
> подобные трюки?


Если код работает с низкоуровневым API, то очень большой. И, что хуже, является причиной трудноуловимых ликов.

Ну а в целом пример заимствован из языка Ada, там он востребован :)


 
DiamondShark ©   (2011-04-12 01:23) [91]


> oxffff ©   (11.04.11 21:19) [89]
> это можно сказать бесплатно.

Посмотрим, сколько стоит "бесплатно".

0. Локальная переменная в инициализаторе

procedure TMyAutoRecord.AfterConstruction
var
 A: TMyAutoRecord;
begin
//
end;

Что делать с бесконечной рекурсией?

1. Копирование.

var
 A, B: TMyAutoRecord;
begin
//...
A := B;
//...
end;

Что произойдёт со старым значением A? Вызывать ли финализатор?
Что произойдёт при выходе из видимости двух идентичных копий? Два вызова финализатора, очевидно. И нет никакой возможности в финализаторе определить, что копия значения уже была финализирована. Как собираемся документировать такое поведение?

2. Копирование в поле объекта.

Всё то же самое, плюс инициализация в конструкторе и финализация в деструкторе.

3. Динамическое распределение.

type
PMyAutoRecord = ^TMyAutoRecord;
var
A : PMyAutoRecord;
begin
new(A);
dispose(A);
end;

Вызов инициализатора в new и финализатора в dispose.

4. Разные способы передачи параметра

procedure Bar(A: TMyAutoRecord);
procedure Bar(var A: TMyAutoRecord);
procedure Bar(const A: TMyAutoRecord);
procedure Bar(out A: TMyAutoRecord);
function Foo: TMyAutoRecord;

Скажи навскидку, какое поведение будет реализовано в каждом случае?
Теперь реализуй и задокументируй.

"Бесплатно", блин. А без перекрытия операции копирования ещё и принципиально глюкаво.


 
DiamondShark ©   (2011-04-12 01:44) [92]


> хотелось бы добавить финты С++.

Хм, финты...

You should not construct two auto_ptr<Type> objects that own the same object.

Т.е. в С++ те же самые проблемы с корректным копированием. И это несмотря на возможность перекрытия копирования!

А оно надо -- повторять чужие грабли?


 
Mystic ©   (2011-04-12 01:51) [93]


> DiamondShark ©   (12.04.11 01:23) [91]


1. Я же писал, есть метод Adjust, который вызывается в случае копирования. Итого на строке A := B вызовется

A.Finalize();
внутренняя функция копирования
A.Adjust();

При этом компилятор считает, что Initialize + Finalize = 0 (сокращается), поэтому если мы видим, что A до этого не использовалось, то эти методы не дергаются.

Если метод Adjust неопределен, то копирование запрещено.

2. А тут что за проблемы? Скопировали и забыли :)

3. Аналогично. Вызвали New, вызвался Initialize. Вызвался Dispose, вызвался Finalize.

4.
procedure Bar(A: TMyAutoRecord);
Копирование параметра, строго говоря, Initialize, Finalize, копирование + Adjust. Initialize + Finalize = 0, поэтому сокращается до копирование + Adjust.

procedure Bar(var A: TMyAutoRecord);
Очевидно ничего

procedure Bar(const A: TMyAutoRecord);
Очевидно ничего, разновидность var

procedure Bar(out A: TMyAutoRecord);
Очевидно ничего, разновидность var

function Foo: TMyAutoRecord; = procedure(var Result: TMyAutoRecord);


 
_oxfffff   (2011-04-12 10:27) [94]


> DiamondShark ©   (12.04.11 01:23) [91]
>
> > oxffff ©   (11.04.11 21:19) [89]
> > это можно сказать бесплатно.
>
> Посмотрим, сколько стоит "бесплатно".
>
> 0. Локальная переменная в инициализаторе
>
> procedure TMyAutoRecord.AfterConstruction
> var
>  A: TMyAutoRecord;
> begin
> //
> end;
>
> Что делать с бесконечной рекурсией?


1. А что делать с остальной бесконечной рекурсией в программах?
2. Hint компилятора.


 
Дмитрий С ©   (2011-04-12 10:35) [95]

А практическая значимость?


 
oxffff ©   (2011-04-12 10:36) [96]


> function Foo: TMyAutoRecord; = procedure(var Result: TMyAutoRecord);


Не всегда.


 
oxffff ©   (2011-04-12 10:37) [97]


> Дмитрий С ©   (12.04.11 10:35) [95]
> А практическая значимость?


Нормально реализовать

http://blog.barrkel.com/2010/01/one-liner-raii-in-delphi.html
http://blog.barrkel.com/2008/09/smart-pointers-in-delphi.html


 
oxffff ©   (2011-04-12 10:39) [98]


> oxffff ©   (12.04.11 10:36) [96]
>
> > function Foo: TMyAutoRecord; = procedure(var Result: TMyAutoRecord);
>
>
>
> Не всегда.


В смысле я имею ввиду не только записи.


 
oxffff ©   (2011-04-12 10:51) [99]


> DiamondShark ©   (12.04.11 01:23) [91]


Я не собираюсь повторять аналог семантики С++.
Это просто события, а не семантика финализации, инициализации, копирования.
Также можно добавить событие копирования.


 
DiamondShark ©   (2011-04-12 12:54) [100]


> oxffff ©   (12.04.11 10:51) [99]

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

Если тебе не надо копировать семантику Ц++, введи в язык просто типизированные смартпоинтеры с подсчётом ссылок. Реализовать можешь по аналогии с AnsiString: выделять в памяти блок с префиксом счётчика ссылок, поинтер указывает на начало данных. Получаем прозрачную совместимость с обычным поинтером. Это будет полезная вещь.


> http://blog.barrkel.com/2010/01/one-liner-raii-in-delphi.html

Чушь собачья.


 
Дмитрий С ©   (2011-04-12 19:35) [101]


> Чушь собачья.

Согласен, как и идея "программирование для программирования".


 
_Юрий   (2011-04-12 20:08) [102]


> Чушь собачья.
>

Очень удобно для случаев, когда блок финализации должен быть выполнен или не выполнен в зависимости от условий, определяемых в середине скоупа


 
DiamondShark ©   (2011-04-12 20:17) [103]


> _Юрий   (12.04.11 20:08) [102]

Вся беда только в том, что по ссылке -- безусловная финализация в конце скопа.


 
oxffff ©   (2011-04-12 20:21) [104]


> > http://blog.barrkel.com/2010/01/one-liner-raii-in-delphi.
> html
>
> Чушь собачья.


Довольно смело, но странно осуждать идею инженера компилятора Delphi.
Ну, как говорится, сколько людей, столько и мнений.


 
_Юрий   (2011-04-12 20:29) [105]


> DiamondShark ©   (12.04.11 20:17) [103]
>
>


Она безусловна после того, как ее инициализировали. Ее можно инициализировать по условию


 
DiamondShark ©   (2011-04-13 01:40) [106]


> oxffff ©   (12.04.11 20:21) [104]
> Довольно смело, но странно осуждать идею инженера компилятора Delphi.

Ох ты ж ЁТНХ. Инженер компилятора Delphi малость слоупок. Этой идеей пользовались с тех пор, как в Delphi появились интерфейсы, т.е. так примерно лет 15 уже. Идея бродила в этом вашем фидо ещё когда "инженер компилятора Delphi" тёлок за косички дёргал и получал томом английской грамматики по башке.
Сам пользовался ещё в delphi 3, потом забил: возни много, толку мало.

Вердикт "Чушь собачья" является не мнением, а фактом, проверенным временем.


> Ну, как говорится, сколько людей, столько и мнений.

А Истина -- одна.


 
oxffff ©   (2011-04-13 09:34) [107]


> DiamondShark ©   (13.04.11 01:40) [106]


А что же это за идея такая? Можно код.


 
DiamondShark ©   (2011-04-13 11:54) [108]


> oxffff ©   (13.04.11 09:34) [107]

Пил вчера?


 
oxffff ©   (2011-04-13 12:15) [109]


> DiamondShark ©   (13.04.11 11:54) [108]
>
> > oxffff ©   (13.04.11 09:34) [107]
>
> Пил вчера?


Нет. Ты код давай.


 
DiamondShark ©   (2011-04-13 13:27) [110]


> oxffff ©   (13.04.11 12:15) [109]

Прикольный получается диалог:

-- Вот идея инженера компилятора Delphi.
-- Этой идее уже 15 лет.
-- А что же это за идея такая?

Ты либо пьян, либо толсто тролишь.


 
_oxffff   (2011-04-13 14:44) [111]


> DiamondShark ©   (13.04.11 13:27) [110]
>
> > oxffff ©   (13.04.11 12:15) [109]
>
> Прикольный получается диалог:
>
> -- Вот идея инженера компилятора Delphi.
> -- Этой идее уже 15 лет.
> -- А что же это за идея такая?
>
> Ты либо пьян, либо толсто тролишь.

>Сам пользовался ещё в delphi 3, потом забил: возни много, толку мало.



Мне понятна идея инженера, но совершенно не понятна идея, которую ты использовал в Delphi 3.
Вот я прошу код идеи, которую ты использовал в Delphi 3,
с которой ты возился очень долго, а в итоге выхлопа не было.

А то твои намеки о том, что идея инженера эквивалент идеи, которую ты использовал в Delphi 3 мягко говоря плохо пахнут.


 
jack128_   (2011-04-13 16:27) [112]


> А то твои намеки о том, что идея инженера эквивалент идеи,
>  которую ты использовал в Delphi 3 мягко говоря плохо пахнут.
>

абсолютно эквивалентны. принцип один и тот же, автоподсчет ссылок на интерфейс.


 
DiamondShark ©   (2011-04-13 16:29) [113]


> _oxffff   (13.04.11 14:44) [111]

Поскольку, я не могу поверить, что тебе не понятно слово "эта", то мне остаётся только предположить, что ты в "идее инженера" видишь то, чего там либо нет, либо не видно мне.

Изложи, пожалуйста, своими словами, как ты понял "идею инженера".


 
oxffff ©   (2011-04-13 16:44) [114]


> jack128_   (13.04.11 16:27) [112]
>
> > А то твои намеки о том, что идея инженера эквивалент идеи,
>
> >  которую ты использовал в Delphi 3 мягко говоря плохо
> пахнут.
> >
>
> абсолютно эквивалентны.


C точки зрения семантики интерфейсов. Согласен.
А с точки зрения In place объявления. Не согласен.


 
oxffff ©   (2011-04-13 16:45) [115]


> DiamondShark ©   (13.04.11 16:29) [113]


Задняя передача?

[112]


 
DiamondShark ©   (2011-04-13 17:07) [116]


> А с точки зрения In place объявления. Не согласен.

С точки зрения In place объявления сильно мешало отсутствие анонимных методов с замыканием.

Но у меня было asm-шаманство с указателем на локальную процедуру ;)
Т.е., где-то так:

type
 TScopeExitNotifier = class(TInterfacedObject)
 private
   FProc: Pointer;
 public
   constructor Create(const AProc: Pointer);
   destructor Destroy; override;
 end;

constructor TScopeExitNotifier.Create(const AProc: Pointer);
begin
 FProc := AProc;
end;

destructor TScopeExitNotifier.Destroy;
begin
 if Assigned(FProc) then
 asm
    // тут шаманство со стеком и вызов локальной процедуры по FProc
 end;
 inherited;
end;

function MakeScopeExitNotifier(const AProc: Pointer): IInterface;
begin
 Result := TScopeExitNotifier.Create(AProc);
end;


asm-шаманство по памяти не воспроизведу.


procedure Main;
 procedure ScopeExitProc;
 begin
   ...
 end;
begin
 MakeScopeExitNotifier(@ScopeExitProc);
 ...
end;


Без полноценных замыканий стрёмно, конечно.
Но в таком виде оно известно со времён Дельфи3 и вовсю гуляло по федо.

А с замыканиями и я многим старым финтам новую жизнь могу придумать.


 
_oxffff   (2011-04-13 17:19) [117]


> А с замыканиями и я многим старым финтам новую жизнь могу
> придумать.


О том и речь. Это безопасней, чем использование вложенных процедур и функций, в которых запрещено обращение out of inner scope, в противном случае шамаство с ASM становится нетривиальным под каждую процедуру. Ну или полная копия между [esp,ebp] интервалом, что накладно.



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

Форум: "Прочее";
Текущий архив: 2011.07.31;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.69 MB
Время: 0.008 c
2-1303423377
Gu
2011-04-22 02:02
2011.07.31
Формирование магнитных ссылок


15-1302090541
oxffff
2011-04-06 15:49
2011.07.31
AfterConstruction, beforedestruction у record


2-1303719929
.code
2011-04-25 12:25
2011.07.31
объект в property


15-1302428314
ddd329
2011-04-10 13:38
2011.07.31
С Win32 на .NET


2-1303392541
барсук
2011-04-21 17:29
2011.07.31
Как вывести список IP, к которым стороняя программа подключена





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский