В конфе в очередной раз зашел разговор за горячую замену кода в ББ. У народа оказывается с этим есть проблемы. И более того говорят что ее там нет!
Сначала было непонятно, что собственно хотят изобразить. Теперь же есть пример проблемного кода:
MODULE A;
IMPORT StdLog;
TYPE
T0* = EXTENSIBLE RECORD END;
PT* = POINTER TO T0;
VAR
r* : PT;
PROCEDURE (ob : PT) Some*(), NEW, EXTENSIBLE;
BEGIN
StdLog.Int(42);
END Some;
PROCEDURE Test*(); BEGIN
r.Some()
END Test;
BEGIN
END A.
MODULE B;
IMPORT A, StdLog;
TYPE
T1* = RECORD (A.T0) END;
PT* = POINTER TO T1;
VAR
r : PT;
PROCEDURE (ob : PT) Some*();
BEGIN
StdLog.Int(13)
END Some;
PROCEDURE Test*();
BEGIN
NEW(r);
A.r := r;
A.Test();
END Test;
END B.
(!) B.Test
Unload B
(!) A.Test
Trap
https://gist.github.com/valexey/7777367Вах! Вот ведь неразрешимый трабл! Если модуль-владелец отдает свой объект в другой модуль, то ББ не отслеживает при вызове методов, что модуль-владелец может быть выгружен. То что мы в данном случае получаем
штатный трап народ не впечатлило. Тот факт, что эта ошибка уровня разыменования NIL (что как бэ намекает) никого тоже не колышит:
[01:44:23] <vlad2> boris_ilov: это хреновый трап и принципиально не такой как в случа NIL
Хотя лично я разницы не вижу (и ББ тоже не видит, в чем легко убедиться заглянув в исходники)
Теперь по обсуждаемому коду.
Совершенно очевидно, что этот код не будет работать. Что автор хотел получить от ББ для меня загадка. ББ не подгружает модуль если его прямо или косвенно не импортировать. Неявный импорт средой не отслеживается очевидно по соображениям производительности.
НО! Даже если бы ББ это делал, то это не помогло бы автору. Ибо проблема рук и лени средствами среды не лечится.
Если автор хотел горячую замену реализации в реальном времени, то очевидно, что это делается не так. И это известно любому, кто читал документацию.
Уже неоднократно говорилось о паттерне Dir (который собсна и описан в доке). Народ упрямо игнорит сию информацию.
Горячая замена с паттерном Dir делается элементарно и безопасно.
Почему-то я делал такое ни один раз и никаких AV не получал. Более того я даже не знал что ББ не отслеживает выгрузку модуля. И все потому, что мне в голову не приходило изобразить такой код. Паттерн Dir - это первое, что я вспомню если мне нужно подменить реализацию в реальном времени.
Так в чем же проблема? В ББ? Или в нежелании использовать ООП, в ООП-языке?