В моей задаче требуется получить некоторую информацию от ОС, заполнив глобальные переменные полученными значениями.
Для примера я взял
## Код:
```
VAR
      message-: Dialog.String;
```

Модуль при инициализации должен получить некоторое значение от ОС и поместить его в переменнуюmessage.
Прочтя раздел 3.4 в руководстве Блэкбокса (Design Practices: Object creation), я попытался создать модуль абстракций и модуль реализации (якобы платформо-зависимый). Но для получения переменнойmessageмне нужно создать модель с помощью модель.dir.New() в коде клиента.

Как (если возможно) избавиться отInf := ModelsCore.dir.New();в коде клиента, перенеся внутрь реализации эту строку?

## Код:
```
MODULE TestModelsCore;

   IMPORT Dialog;
   
   TYPE
      Info* = POINTER TO ABSTRACT RECORD END;
      Directory* = POINTER TO ABSTRACT RECORD END;
   
   VAR
      message-: Dialog.String;
      dir-, stdDir-: Directory;

   (** Directory **)

   PROCEDURE (d: Directory) New* (): Info, NEW, ABSTRACT;

   (* Info *)   

   PROCEDURE (I: Info) SetMessage* (IN mes: ARRAY OF CHAR), NEW;
   BEGIN
      message := mes$
   END SetMessage;

   PROCEDURE (I: Info) RetrieveInformation* (OUT mes: ARRAY OF CHAR), NEW, ABSTRACT;

   PROCEDURE (I: Info) InitMessage*, NEW;
      VAR mes: Dialog.String;
   BEGIN
      I.RetrieveInformation(mes);
      I.SetMessage(mes$)
   END InitMessage;

   PROCEDURE SetDir* (d: Directory);
   BEGIN
      ASSERT(d # NIL, 20);
      dir := d;
      IF stdDir = NIL THEN stdDir := d END
   END SetDir;
   
END TestModelsCore.
```


## Код:
```
MODULE TestModelsHost;

   IMPORT Kernel, ModelsCore := TestModelsCore;
      
   TYPE
      Info = POINTER TO RECORD (ModelsCore.Info) END;
      Directory = POINTER TO RECORD (ModelsCore.Directory) END;
   
   VAR
      dir: Directory;
   
   (* Implementation *)
   
   PROCEDURE (I: Info) RetrieveInformation (OUT mes: ARRAY OF CHAR);
   BEGIN
      mes := "Hello!"
   END RetrieveInformation;
   
   (* Directory *)
   PROCEDURE (d: Directory) New (): Info;
   VAR Inf: Info;
   BEGIN
      NEW(Inf);
      Inf.InitMessage;
      RETURN Inf
   END New;
   
   PROCEDURE Init;
   BEGIN
      NEW(dir);
      ModelsCore.SetDir(dir)
   END Init;
   
BEGIN
   Init
END TestModelsHost.
```


## Код:
```
MODULE TestModels;

   IMPORT ModelsHost := TestModelsHost, ModelsCore := TestModelsCore, Log := StdLog;
   
   PROCEDURE Do*;
      VAR Inf: ModelsCore.Info;
   BEGIN
      Inf := ModelsCore.dir.New();
      Log.String(ModelsCore.message); Log.Ln;
      Inf.SetMessage ("Hello, world!");
      Log.String(ModelsCore.message); Log.Ln
   END Do;
   
END TestModels.

^Q TestModels.Do
```

Вложение:TestModels.zip[2.34 КБ]
Скачиваний: 414
