Форум: "Прочее";
Текущий архив: 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