OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Воскресенье, 28 Апрель, 2024 00:36

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




Начать новую тему Ответить на тему  [ Сообщений: 31 ]  На страницу 1, 2  След.
Автор Сообщение
СообщениеДобавлено: Суббота, 11 Март, 2023 16:07 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
Коллеги, в связи с работой над краткой сводкой возник следующий вопрос о некоторой, на мой взгляд, избыточности атрибутов для записей и методов в Компонентном Паскале.
Например, процедура с атрибутом EMPTY может быть заменена процедурой с атрибутом NEW с пустым телом. При этом нет запрета на наличие в списке формальных параметров OUT-параметров. Поэтому с моей точки зрения атрибут EMPTY избыточен. Также, на мой взгляд, для методов избыточен атрибут NEW, поскольку проверить наличие процедур с одинаковым именем можно и без этого атрибута. Для типа записи с атрибутом LIMITED можно обойти ограничения на создание экземпляра только в описывающем модуле - через экспорт и расширение примерно так же, как для типа записи с атрибутом ABSTRACT. Поэтому наличие атрибута LIMITED, с моей точки зрения, тоже под вопросом.
Так же для экспорта методов "implement-only" с запретом прямого вызова из импортирующего модуля - насколько в реальной практике встречается необходимость такого?

Буду рад, если опытные программисты поделятся своим мнением на эту тему и приведут объяснения "на пальцах", когда им был необходим именно тот тип атрибута, который я считаю излишним.

С уважением, Александр.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 18:33 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
NEW нужен для отлавливания опечаток. без него можно опечататься в имени метода для записи-расширения, и компилятор молча это соберёт.
Код:
TYPE
  R0 = EXTENSIBLE RECORD END;
  R1 = RECORD (R0) END;

  PROCEDURE (VAR r: R0) Something; BEGIN … END Something;

  (* а вот тут мы хотели переопределить `Something`, но опечатались в одной букве *)
  PROCEDURE (VAR r: R1) Someting; BEGIN … END Someting;

без NEW этот код соберётся, но делать будет явно не то, что программист задумал. с NEW же компилятор сразу выругается.

атрибут EMPTY — это реально просто замена пустого тела. нужен в основном для того, чтобы при чтении кода различать случаи, когда метод следует реализовать в наследниках, или у нас валидная пустая реализация. или точнее: EMPTY обозначает опциональные интерфейсы, которые можно не реализовывать.

LIMITED-записи нельзя больше расширять, поэтому обойти не получится.

экспорт типа «implementation-only» очень широко используется в фабриках. например, у записи есть метод `Init`, который имеет право вызывать только фабрика, а пользователь — не имеет. поэтому мы объявляем его в интерфейсе как «implementation-only export». фабрика может его вызывать, потому что интерфейс описан в том же модуле; а вот пользователи уже не могут, и мы застрахованы от ошибок повторной инициализации.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 18:41 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
arisu писал(а):
NEW нужен для отлавливания опечаток. без него можно опечататься в имени метода для записи-расширения, и компилятор молча это соберёт.
Код:
TYPE
  R0 = EXTENSIBLE RECORD END;
  R1 = RECORD (R0) END;

  PROCEDURE (VAR r: R0) Something; BEGIN … END Something;

  (* а вот тут мы хотели переопределить `Something`, но опечатались в одной букве *)
  PROCEDURE (VAR r: R1) Someting; BEGIN … END Someting;

без NEW этот код соберётся, но делать будет явно не то, что программист задумал. с NEW же компилятор сразу выругается.

атрибут EMPTY — это реально просто замена пустого тела. нужен в основном для того, чтобы при чтении кода различать случаи, когда метод следует реализовать в наследниках, или у нас валидная пустая реализация. или точнее: EMPTY обозначает опциональные интерфейсы, которые можно не реализовывать.

LIMITED-записи нельзя больше расширять, поэтому обойти не получится.

экспорт типа «implementation-only» очень широко используется в фабриках. например, у записи есть метод `Init`, который имеет право вызывать только фабрика, а пользователь — не имеет. поэтому мы объявляем его в интерфейсе как «implementation-only export». фабрика может его вызывать, потому что интерфейс описан в том же модуле; а вот пользователи уже не могут, и мы застрахованы от ошибок повторной инициализации.

Для атрибута LIMITED расширение разрешено:
Код:
MODULE TestTemp;
TYPE
   a=LIMITED RECORD END;
   b=LIMITED RECORD(a) b: INTEGER END;
VAR
END TestTemp.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 18:53 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
AlexBogy писал(а):
Для атрибута LIMITED расширение разрешено
только в том же самом модуле. из других модулей уже нельзя.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 19:04 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
arisu писал(а):
AlexBogy писал(а):
Для атрибута LIMITED расширение разрешено
только в том же самом модуле. из других модулей уже нельзя.

Да, вы правы.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 19:11 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
кстати, как явный пример «implementation-only export». метод `FINALIZE` объявлен как раз так, потому что его имеет право вызывать только Kernel при сборке мусора, а пользователи — нет.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 19:14 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
arisu писал(а):
кстати, как явный пример «implementation-only export». метод `FINALIZE` объявлен как раз так, потому что его имеет право вызывать только Kernel при сборке мусора, а пользователи — нет.

Спасибо за хороший пример.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 19:21 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
arisu писал(а):
AlexBogy писал(а):
Для атрибута LIMITED расширение разрешено
только в том же самом модуле. из других модулей уже нельзя.

Хотя запись без атрибутов тоже нельзя расширить в импортирующем модуле.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 19:24 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
AlexBogy писал(а):
arisu писал(а):
AlexBogy писал(а):
Для атрибута LIMITED расширение разрешено
только в том же самом модуле. из других модулей уже нельзя.

Хотя запись без атрибутов тоже нельзя расширить в импортирующем модуле.
при помощи LIMITED можно запретить расширять запись-наследника ABSTRACT, например. без LIMITED любые экспортированые реализации абстрактных интерфейсов можно было бы расширять в других модулях, а это не всегда допустимо.

p.s.: а! вы имеете в виду, что если не ставить наследнику явно EXTENSIBLE, то нельзя будет? тут есть ещё такой нюанс, что LIMITED запрещает и создание таких записей вне модуля-определения. то есть, если объявить `POINTER TO LIMITED RECORD`, то вы не сможете сделать `NEW` для такой записи. а если не указывать LIMITED — то сможете. (или, если без POINTER, то не сможете объявить переменную такого типа вообще.)

опять таки, удобно, чтобы объекты никто не создавал вручную помимо фабрик.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 19:38 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
p.s.: а! вы имеете в виду, что если не ставить наследнику явно EXTENSIBLE, то нельзя будет? тут есть ещё такой нюанс, что LIMITED запрещает и создание таких записей вне модуля-определения. то есть, если объявить `POINTER TO LIMITED RECORD`, то вы не сможете сделать `NEW` для такой записи. а если не указывать LIMITED — то сможете.

Если брать ваш пример, то да. Но имеет ли смысл такое действие - экспортировать и не создавать? Проще в таком случае просто не экспортировать.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 19:45 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
arisu писал(а):
кстати, как явный пример «implementation-only export». метод `FINALIZE` объявлен как раз так, потому что его имеет право вызывать только Kernel при сборке мусора, а пользователи — нет.

И в этом случае - не проще ли этот метод не экспортировать?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 20:03 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
AlexBogy писал(а):
arisu писал(а):
кстати, как явный пример «implementation-only export». метод `FINALIZE` объявлен как раз так, потому что его имеет право вызывать только Kernel при сборке мусора, а пользователи — нет.

И в этом случае - не проще ли этот метод не экспортировать?
и как тогда переопределять его для своих записей? переопределять неэкспортированые методы нельзя.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 20:06 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
AlexBogy писал(а):
Если брать ваш пример, то да. Но имеет ли смысл такое действие - экспортировать и не создавать? Проще в таком случае просто не экспортировать.
а как тогда с объектом работать? вот у нас есть объект, который создавать имеет право только фабрика. как с ним работать, если не экспортировать? LIMITED может расширить интерфейс дополнительными методами, например.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 20:07 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
arisu писал(а):
AlexBogy писал(а):
arisu писал(а):
кстати, как явный пример «implementation-only export». метод `FINALIZE` объявлен как раз так, потому что его имеет право вызывать только Kernel при сборке мусора, а пользователи — нет.

И в этом случае - не проще ли этот метод не экспортировать?
и как тогда переопределять его для своих записей? переопределять неэкспортированые методы нельзя.

За каркас не скажу, к сожалению, я не системный программист. Но ваш аргумент убедителен.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 20:12 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
arisu писал(а):
AlexBogy писал(а):
Если брать ваш пример, то да. Но имеет ли смысл такое действие - экспортировать и не создавать? Проще в таком случае просто не экспортировать.
а как тогда с объектом работать? вот у нас есть объект, который создавать имеет право только фабрика. как с ним работать, если не экспортировать? LIMITED может расширить интерфейс дополнительными методами, например.

Вы создали абстрактную запись, расширили ее до LIMITED, далее экспортируете - и не можете с ней работать? Или я что-то не понял в цепи ваших доводов?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 20:33 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
абстрактная запись создаётся в одном модуле. экспортированая LIMITED-реализация с некоторыми расширениями — совсем в другом. в этом другом у нас есть фабрика для производства этих LIMITED. таким образом мы защищаемся от попытки создать LIMITED-запись вне фабрики, но позволяем использовать её (записи) расширеный интерфейс.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 20:37 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
arisu писал(а):
абстрактная запись создаётся в одном модуле. экспортированая LIMITED-реализация с некоторыми расширениями — совсем в другом. в этом другом у нас есть фабрика для производства этих LIMITED. таким образом мы защищаемся от попытки создать LIMITED-запись вне фабрики, но позволяем использовать её (записи) расширеный интерфейс.

Это понятно. А если использовать расширение экспортированного абстракта не в LIMITED, а в обычной записи без атрибутов? Как я понимаю, вы ведь не экспортируете LIMITED наружу?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 21:13 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
arisu писал(а):
NEW нужен для отлавливания опечаток. без него можно опечататься в имени метода для записи-расширения, и компилятор молча это соберёт.
Код:
TYPE
  R0 = EXTENSIBLE RECORD END;
  R1 = RECORD (R0) END;

  PROCEDURE (VAR r: R0) Something; BEGIN … END Something;

  (* а вот тут мы хотели переопределить `Something`, но опечатались в одной букве *)
  PROCEDURE (VAR r: R1) Someting; BEGIN … END Someting;

без NEW этот код соберётся, но делать будет явно не то, что программист задумал. с NEW же компилятор сразу выругается.

атрибут EMPTY — это реально просто замена пустого тела. нужен в основном для того, чтобы при чтении кода различать случаи, когда метод следует реализовать в наследниках, или у нас валидная пустая реализация. или точнее: EMPTY обозначает опциональные интерфейсы, которые можно не реализовывать.

LIMITED-записи нельзя больше расширять, поэтому обойти не получится.

экспорт типа «implementation-only» очень широко используется в фабриках. например, у записи есть метод `Init`, который имеет право вызывать только фабрика, а пользователь — не имеет. поэтому мы объявляем его в интерфейсе как «implementation-only export». фабрика может его вызывать, потому что интерфейс описан в том же модуле; а вот пользователи уже не могут, и мы застрахованы от ошибок повторной инициализации.

Мне понятна ваша аргументация насчет атрибута NEW. Но позволю себе заметить, что она характерна только для методов. При использовании в записях процедурных типов переопределение процедур в расширении решается гораздо проще.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 21:38 

Зарегистрирован: Воскресенье, 25 Декабрь, 2022 23:14
Сообщения: 1167
AlexBogy писал(а):
Это понятно. А если использовать расширение экспортированного абстракта не в LIMITED, а в обычной записи без атрибутов? Как я понимаю, вы ведь не экспортируете LIMITED наружу?
ну, вы спрашивали, зачем может быть полезен LIMITED — это и был пример такой ситуации. не обязательно всегда будет так, но подобные ситуации возникают, и для их разруливания как раз придуман LIMITED. в компонентном паскале авторы старались соблюдать некое равновесие между академической чистотой и грязной практикой, поэтому предоставили методы разруливания задач, которые академически вообще возникнуть были не должны, но в жизни иногда случаются.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 11 Март, 2023 21:43 

Зарегистрирован: Суббота, 30 Июль, 2022 12:02
Сообщения: 68
arisu писал(а):
AlexBogy писал(а):
Это понятно. А если использовать расширение экспортированного абстракта не в LIMITED, а в обычной записи без атрибутов? Как я понимаю, вы ведь не экспортируете LIMITED наружу?
ну, вы спрашивали, зачем может быть полезен LIMITED — это и был пример такой ситуации. не обязательно всегда будет так, но подобные ситуации возникают, и для их разруливания как раз придуман LIMITED. в компонентном паскале авторы старались соблюдать некое равновесие между академической чистотой и грязной практикой, поэтому предоставили методы разруливания задач, которые академически вообще возникнуть были не должны, но в жизни иногда случаются.

Пожалуй, это один из самых сильных аргументов. Благодарю вас.


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

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


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

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


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

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB