OberonCore https://forum.oberoncore.ru/ |
|
Вопрос по атрибутам записей и методов https://forum.oberoncore.ru/viewtopic.php?f=1&t=6916 |
Страница 2 из 2 |
Автор: | arisu [ Суббота, 11 Март, 2023 21:44 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
AlexBogy писал(а): Мне понятна ваша аргументация насчет атрибута NEW. Но позволю себе заметить, что она характерна только для методов. При использовании в записях процедурных типов переопределение процедур в расширении решается гораздо проще. это просто два разных подхода к одному и тому же. опять таки: авторы компонентного паскаля посчитали, что методы людям более привычны и удобны, и обеспечили средства отлавливать явные ошибки в их описании.технически методы удобней, потому что при создании расширений не надо руками копировать всю таблицу виртуальных методов (ведь опсиание процедурных полей в записи — это и есть обычная таблица виртуальных методов), и сложнее забыть какое-нибудь присваивание (точнее, невозможно, потому что эти присваивания генерирует компилятор). но в принципе — оба варианта имеют право на жизнь, не то чтобы какой-то из них был однозначно лучше другого. |
Автор: | AlexBogy [ Среда, 22 Март, 2023 06:52 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
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 метод Someting будет делать то, что хочет программист, за исключением одного - он не сможет вызвать супервызов, но это будет отловлено на этапе компиляции. И запись R1 будет содержать не один метод, а два, что увеличит расход памяти на один указатель. |
Автор: | arisu [ Среда, 22 Март, 2023 07:25 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
определённо не то. Код: PROCEDURE DoIt (VAR r: R0); тут мы ожидаем, что `DoIt()` вызовет `R1.Something()` — но её не существует из-за опечатки. о чём программист будет не в курсе, потому что компилятор не сообщил. в итоге выполнится совсем не тот метод, который ожидает программист, и такую ошибку можно искать очень-очень долго.
BEGIN r.Something END DoIt; VAR rec: R1; … DoIt(rec) |
Автор: | AlexBogy [ Среда, 22 Март, 2023 07:46 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
arisu писал(а): определённо не то. Код: PROCEDURE DoIt (VAR r: R0); тут мы ожидаем, что `DoIt()` вызовет `R1.Something()` — но её не существует из-за опечатки. о чём программист будет не в курсе, потому что компилятор не сообщил. в итоге выполнится совсем не тот метод, который ожидает программист, и такую ошибку можно искать очень-очень долго.BEGIN r.Something END DoIt; VAR rec: R1; … DoIt(rec) Я, конечно, не знаток компиляторов, но вообще-то, по моим представлениям, вызов несуществующей функции должен отлавливаться на этапе компиляции, ведь так? Или вы имеете в виду, что будет вызвана не функция не R1.Someting, а R0.Something? |
Автор: | arisu [ Среда, 22 Март, 2023 08:24 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
AlexBogy писал(а): Или вы имеете в виду, что будет вызвана не функция не R1.Someting, а R0.Something? именно так. поскольку мы выше договорились, что в названии опечатка — то получилось совсем не то, что задумывал автор начальной реализации, и совсем не то, что задумывал пользователь этой реализации. а с NEW такая ситуация отловится ещё на стадии компиляции.
|
Автор: | AlexBogy [ Пятница, 07 Апрель, 2023 19:02 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
arisu писал(а): AlexBogy писал(а): Или вы имеете в виду, что будет вызвана не функция не R1.Someting, а R0.Something? именно так. поскольку мы выше договорились, что в названии опечатка — то получилось совсем не то, что задумывал автор начальной реализации, и совсем не то, что задумывал пользователь этой реализации. а с NEW такая ситуация отловится ещё на стадии компиляции.Пользуясь темой, прошу вас прояснить еще такой вопрос. Одним из факторов, способствовавших появлению атрибута EXTENSIBLE, является то, что указатель на запись в КП может быть базовым типом для расширения. Насколько велика была необходимость такого нововведения и что он может дать программисту? |
Автор: | arisu [ Суббота, 08 Апрель, 2023 10:47 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
тут два вопроса. про тип: это всё из той же серии практических удобств. `A = POINTER TO RECORD` — это, в общем-то, пример довольно редкого в CP синтаксического сахара. омики на опыте разработки своей системы сделали в CP несколько таких добавлений. POINTER TO RECORD — используется очень часто, вся система ведь построена на динамическом создании компонентов. также соответствие для POINTER TO ARRAY структурное, так что два POINTER TO ARRAY OF INTEGER, объявленые в разных местах будут совместимы. кратко: избавляет от совершенно лишнего печатанья, ничего при этом в системе не нарушая. используется такая конструкция повсеместно (реально повсеместно), так что вполне оправданый шаг. оно и читается в итоге проще, чем `A = POINTER TO ADesc; ADesc = RECORD …`. омики, не забываем, были практики: они не только систему написали, они её ещё и использовали. и уже при написании им надоело каждый раз совершенно ненужные Desc-и объявлять. помимо всего прочего — это действительно делает код для читателя яснее. если есть объявление как `A`, так и `ADesc` (см. выше) — нельзя с уверенностью сказать, что нигде ниже по коду модуля не делается `VAR a: ADesc`. а если только `A` — то можно. так что сахар ещё и повышает читаемость исходника. а EXTENSIBLE с этим не связано: расширять-то можно и просто RECORD. это, по большому счёту, снова для читаемости кода: видим `EXTENSIBLE` — сразу понимаем, что перед нами заготовка, которую пользователь потом может подпиливать под свои нужды. простите за многословие, чот не очень чётко поутру соображаю. надеюсь, получилось не очень непонятно. |
Автор: | AlexBogy [ Воскресенье, 09 Апрель, 2023 14:07 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
arisu писал(а): тут два вопроса. про тип: это всё из той же серии практических удобств. `A = POINTER TO RECORD` — это, в общем-то, пример довольно редкого в CP синтаксического сахара. омики на опыте разработки своей системы сделали в CP несколько таких добавлений. POINTER TO RECORD — используется очень часто, вся система ведь построена на динамическом создании компонентов. также соответствие для POINTER TO ARRAY структурное, так что два POINTER TO ARRAY OF INTEGER, объявленые в разных местах будут совместимы. Вы считаете, что такая совместимость стоит такого? Код: MODULE TempTest;
IMPORT Log; TYPE a=POINTER TO ARRAY OF INTEGER; b=POINTER TO ARRAY OF INTEGER; VAR pa:a; pb:b; BEGIN NEW(pa,10); NEW(pb,20); pb:=pa; Log.Int(pb^[10]); Log.Ln; END TempTest. |
Автор: | arisu [ Воскресенье, 09 Апрель, 2023 20:51 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
это сделано для штук типа `PROCEDURE A (arr: POINTER TO ARRAY OF INTEGER)` и подобного. особых проблем тут не вижу. структурная совместимость заканчивается на базовых типах, так что если надо конкретно несовместимое — то есть стандартная идиома: Код: TYPE A = POINTER TO ARRAY OF RECORD v: INTEGER END; B = POINTER TO ARRAY OF RECORD v: INTEGER END; и вот эти типы уже не совместимы. |
Автор: | Comdiv [ Понедельник, 10 Апрель, 2023 12:51 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
AlexBogy писал(а): Код: ... NEW(pa,10); NEW(pb,20); pb:=pa; Log.Int(pb^[10]); Код: NEW(pb,10); То есть, для ошибки даже не нужно второй переменной и какой либо совместимости по типам.
Log.Int(pb^[10]); |
Автор: | AlexBogy [ Понедельник, 10 Апрель, 2023 15:41 ] |
Заголовок сообщения: | Re: Вопрос по атрибутам записей и методов |
Comdiv писал(а): AlexBogy писал(а): Код: ... NEW(pa,10); NEW(pb,20); pb:=pa; Log.Int(pb^[10]); Код: NEW(pb,10); То есть, для ошибки даже не нужно второй переменной и какой либо совместимости по типам.Log.Int(pb^[10]); Благодарю Вас за подробный ответ. |
Страница 2 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |