Оберон-клуб «ВЄДАsoft»

Твердыня модульных языков
Текущее время: 16 июн 2025, 17:59

Часовой пояс: UTC + 2 часа




Начать новую тему Ответить на тему  [ Сообщений: 14 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Модуль Stores
СообщениеДобавлено: 19 июн 2018, 16:44 
Не в сети

Сообщения: 116
Откуда: Каменск-Уральский
В модуле ObxStores я встретил незнакомые мне конструкции (выделено красным):
IMPORT Dialog, Files, Stores;

TYPE
Node = POINTER TO RECORD (Stores.Store)
a, b: Node
END;

(* Methods of Node *)
PROCEDURE (n: Node) Externalize (VAR w: Stores.Writer);
BEGIN
w.WriteStore(n.a); w.WriteStore(n.b)
END Externalize;

PROCEDURE (n: Node) Internalize (VAR r: Stores.Reader);
VAR s: Stores.Store;
BEGIN
r.ReadStore(s);
IF (s # NIL) & (s IS Node) THEN n.a := s(Node) ELSE n.a := NIL END;
r.ReadStore(s);
IF (s # NIL) & (s IS Node) THEN n.b := s(Node) ELSE n.b := NIL END
END Internalize;

PROCEDURE (n: Node) CopyFrom (source: Stores.Store);
BEGIN
WITH source: Node DO
IF source.a # NIL THEN n.a := Stores.CopyOf(source.a)(Node) ELSE n.b := NIL END;
IF source.b # NIL THEN n.b := Stores.CopyOf(source.b)(Node) ELSE n.b := NIL END
END
END CopyFrom;

PROCEDURE NewGraph (): Node;
VAR n: Node;
BEGIN
NEW(n);
NEW(n.a); Stores.Join(n, n.a);
NEW(n.b); Stores.Join(n, n.b);
n.a.a := n.b; n.a.b := NIL; n.b.a := n.a; n.b.b := n.b;
RETURN n
END NewGraph;

PROCEDURE GraphOk (n: Node): BOOLEAN;
BEGIN
RETURN (n # n.a) & (n # n.b) & (n.a # n.b) & (n.a.a = n.b) & (n.a.b = NIL) & (n.b.a = n.a) & (n.b.b = n.b)
& Stores.Joined(n, n.a) & Stores.Joined(n, n.b)
END GraphOk;


(* Demonstrate Ex- and Internalization *)
PROCEDURE WriteRead*;
VAR n, m: Node; f: Files.File; w: Stores.Writer; r: Stores.Reader; s: Stores.Store;
BEGIN
(* allocate and check new graph *)
n := NewGraph(); ASSERT(GraphOk(n), 1);

(* externalize graph to a temporary file *)
f := Files.dir.Temp();
w.ConnectTo(f); w.WriteStore(n);

(* read graph back from file *)
r.ConnectTo(f); r.ReadStore(s); m := s(Node);

(* check graph to be internalized with nodes correctly linked and joined *)
ASSERT(GraphOk(m), 2);
Dialog.ShowMsg("WriteRead test ok.")
END WriteRead;

Что даёт в типе запись объявление (Stores.Store) после слова RECORD?
Что за странный вызов метода: s(Node), ведь в модуле Store под s сразу несколько методов:
Код: "OBERON"
  1. Store = POINTER TO ABSTRACT RECORD
  2. PROCEDURE (s: Store) Domain (): Domain, NEW;
  3. PROCEDURE (s: Store) CopyFrom- (source: Store), NEW, EMPTY;
  4. PROCEDURE (s: Store) Internalize- (VAR rd: Reader), NEW, EMPTY;
  5. PROCEDURE (s: Store) Externalize- (VAR wr: Writer), NEW, EMPTY;
  6. PROCEDURE (s: Store) ExternalizeAs- (VAR s1: Store), NEW, EMPTY
  7. END;


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Модуль Stores
СообщениеДобавлено: 20 июн 2018, 06:10 
Не в сети

Сообщения: 203
Len писал(а):
В модуле ObxStores я встретил незнакомые мне конструкции (выделено красным):
TYPE
Node = POINTER TO RECORD (Stores.Store)

r.ConnectTo(f); r.ReadStore(s); m := s(Node);

Что даёт в типе запись объявление (Stores.Store) после слова RECORD?
Что за странный вызов метода: s(Node)


Это же основы ООП оберонов.

Node = POINTER TO RECORD (Stores.Store) значит, что запись Node является указателем на запись, которая является расширением записи Store из модуля Stores.
s(Node) в данном случае является преобразованием переменной s типа Store к типу Node, в сишных языках это записывается как (Node)s, Вирт же решил сделать не как в сях, а так, что бы можно было легко спутать с вызовом процедуры.
Ну, скажем, в Аде тоже есть неоднозначность в такой записи -- то ли это вызов функции, то ли обращение к элементу массива...


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Модуль Stores
СообщениеДобавлено: 22 июн 2018, 16:12 
Не в сети

Сообщения: 116
Откуда: Каменск-Уральский
geniepro писал(а):
s(Node) в данном случае является преобразованием переменной s типа Store к типу Node

Зачем вообще преобразовывать переменную s типа Store к типу Node, не проще ли было сразу объявить её как Node?


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Модуль Stores
СообщениеДобавлено: 22 июн 2018, 20:01 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Там же иерархия типов. Потомок может сойти за родителя, т.к. обладает всеми его свойствами. Является, так сказать, родителем плюс. Бывает так, что объявлен указатель типа родитель, а ему присваивают ссылку на потомка. Вот в этом случае и преобразовывают. С Node и Store так же.

Дочь является потомком ПапаМама и ссылка на неё может храниться в указателе типа ПапаМама. Обращение к её индивидуальным полям в этом случае происходит так:
Код: "OBERON"
  1. TYPE
  2. ПапаМама = RECORD ... END;
  3.  
  4. Дочь = RECORD (ПапаМама)
  5. поле_дочери: Тип
  6. END;
  7.  
  8. VAR
  9. человек: POINTER TO ПапаМама;
  10.  
  11. BEGIN
  12. человек(Дочь).поле_дочери

Это безопасное "преобразование", правильность соответствия таких типов и существования нужных полей проверяет компилятор на этапе компиляции или рантайм в момент работы программы.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Модуль Stores
СообщениеДобавлено: 23 июн 2018, 08:36 
Не в сети

Сообщения: 203
Zorko писал(а):
Это безопасное "преобразование", правильность соответствия таких типов и существования нужных полей проверяет компилятор на этапе компиляции или рантайм в момент работы программы.

Вообще-то тут желательно перед преобразованием сделать проверку, действительно ли в переменной типа POINTER TO ПапаМама находится адрес значения типа Дочь, иначе в рантайме может произойти ошибка.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Модуль Stores
СообщениеДобавлено: 23 июн 2018, 09:02 
Не в сети

Сообщения: 203
Len писал(а):
geniepro писал(а):
s(Node) в данном случае является преобразованием переменной s типа Store к типу Node

Зачем вообще преобразовывать переменную s типа Store к типу Node, не проще ли было сразу объявить её как Node?

В ООП это нужно для абстракции алгоритмов. Конечно, можно для каждого типа сделать одинаковый код, делающий что-то. Но если эти типы в чём-то схожи, их можно выстроить в иерархию и обобщить некоторый код.

Есть и другие способы сделать подобное. Например, использовать не полиморфизм наследования, чью теорию в 70-х гг. построила Барбара Лисков, но и использовать параметрический полиморфизм родом из тех же 70-х. Вирт решил идти по пути ООП...


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Модуль Stores
СообщениеДобавлено: 23 июн 2018, 17:09 
Не в сети

Сообщения: 11
Len писал(а):
сразу объявить её как Node?

В r.ReadStore(s) нужен параметр типа Stores.Store, поэтому решили так сделать.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Модуль Stores
СообщениеДобавлено: 25 июн 2018, 14:43 
Не в сети

Сообщения: 116
Откуда: Каменск-Уральский
Ещё вопросик: когда вызывается метод Externalize?
Internalize вызывается автоматически при вызове метода ReadStore, но этот метод вызывается в самом методе Internalize, почему не получается бесконечное зацикливание?


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Модуль Stores
СообщениеДобавлено: 26 июн 2018, 15:38 
Не в сети

Сообщения: 11
Externalize соответственно вызывается когда WriteStore исполняется. Переполнения стека нет, поскольку обычно число вложенных Store ограничено.


Вернуться к началу
 Профиль  
Ответить с цитатой  
 Заголовок сообщения: Re: Модуль Stores
СообщениеДобавлено: 27 июн 2018, 05:00 
Не в сети
Аватара пользователя

Сообщения: 1019
Откуда: Днепропетровская обл.
Иван Денисов писал(а):
Если Externalize реализован для Views.View, то он вызывается при сохранении отображения. В общем случае Externalize вызывается при записи объекта Stores.Store или его наследников с помощью процедуры WriteStore.

Как ответил Сергей, получается, что там идет чтение вложенных хранилищ (Stores.Store), и их число ограничено. Хранилище (Stores.Store) может иметь в своем составе несколько дочерних объектов типа хранилища или их наследников. Вот и получается, что для их чтения необходим рекурсивный вызов.


Вернуться к началу
 Профиль  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 2 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
© VEDAsoft Oberon Club