Здравствуйте, недавно я начал изучать BlackBox, и вот возник такой вопрос :
Предположим, что у нас есть модуль, экспортирующий абстрактный
тип и абстрактную же фабрику для этого типа :
Код:
MODULE A;
TYPE
AbsRec* = POINTER TO ABSTRACT RECORD
END;
AbsDirectory* = POINTER TO ABSTRACT RECORD
END;
VAR
dir- : AbsDirectory;
PROCEDURE (a : AbsRec) Method*, NEW, ABSTRACT;
PROCEDURE (a : AbsDirectory) NewRec*(VAR r : AbsRec), NEW, ABSTRACT;
PROCEDURE SetDir*(newDir : AbsDirectory);
BEGIN
dir := newDir
END SetDir;
PROCEDURE UseAbsRec*;
VAR
r : AbsRec;
BEGIN
dir.NewRec(r);
r.Method
END UseAbsRec;
END A.
И мы написали модуль реализации :
Код:
MODULE B;
IMPORT A, StdLog;
TYPE
Rec = POINTER TO RECORD(A.AbsRec)
END;
Directory* = POINTER TO RECORD(A.AbsDirectory)
END;
VAR
dir : Directory;
PROCEDURE (a : Rec) Method;
BEGIN
StdLog.Ln; StdLog.String("Hi, I'm Rec.Method!")
END Method;
PROCEDURE (a : Directory) NewRec*(VAR r : A.AbsRec);
VAR
nr : Rec;
BEGIN
NEW(nr);
r := nr
END NewRec;
PROCEDURE Register*;
BEGIN
A.SetDir(dir)
END Register;
BEGIN
NEW(dir)
END B.
Вроде бы всё нормально : если вызвать команды B.Register и A.UseAbsRec, в лог будет выведено "Hi, I'm Rec.Method!". Но модуль
A будет использовать тип из модуля B (тип B.Directory), хотя система об этом ничего не знает. Если далее вызвать DevDebug.Unload "B", модуль B спокойно выгрузится, т. к. явных ссылок на него нет, и переменная A.dir окажется невалидной, и попытка её использовать
(напр., A.UseAbsRec), приведёт к trap'у illegal execution.
Для предотвращения этого нужно либо запретить выгрузку модулей вообще, либо ввести что-то вроде "сборщика мусора для модулей".