OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Вторник, 19 Март, 2024 13:41

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




Начать новую тему Ответить на тему  [ Сообщений: 62 ]  На страницу Пред.  1, 2, 3, 4  След.
Автор Сообщение
СообщениеДобавлено: Четверг, 26 Май, 2016 21:33 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Всё равно ведь внутри модуля, где объявллен метод, модификатор read-only не должен работать. Как же теперь быть, глобальные рекорды с методами потеряли смысл.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 26 Май, 2016 21:51 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Пётр, можно пример, что ты имеешь в виду? Туго соображаю что-то )


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 26 Май, 2016 22:05 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
https://gist.github.com/kpmy/b98d9ee2a0 ... 4296bce544

Допустим, я описал свой рекорд, который оборачивает обобщённый список, даёт полезные методы, конвертирует типы, проверяет значения, в общем, обычный такой рекорд. Список лежит внутри рекорда скрытый.

Экземпляр рекорда я разместил в модуле, в переменной objList, сделал её read-only, чтобы никто не заменил мне рекорд, но сам-то я имею право его менять, через официальные методы.

К тому же, методы объявлены внутри модуля ypkDetails, стало быть они имеют полный доступ к переменной objList, а тут выясняется, что больше нельзя вызывать VAR-методы на read-only объекте и менять значения внутри IN-метода.

Итак, вопрос, какую концепцию нарушает вызов метода рекорда для переменной типа ObjList, описанного рядом с рекордом? Мне кажется, никакую концепцию. Я защитил свой объект и свои данные сам, скрыв поле list.

Более того, в случае с read-only record её методы вообще не имеют смысла, ведь они не могут сменить состояние своего же объекта.

Такая вот коллизия. Я думаю, это всё из-за смелого трактования read-only режима переменной/параметра на внутреннее состояние статического объекта доступного по этой переменной.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 27 Май, 2016 00:54 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Пётр Кушнир писал(а):
Экземпляр рекорда я разместил в модуле, в переменной objList, сделал её read-only, чтобы никто не заменил мне рекорд, но сам-то я имею право его менять, через официальные методы.


А с чего ты взял, что имеешь право? )
Только если имеешь доступ полный к объекту.

Вот изнутри этого модуля, в Init каком-нибудь и т.п. - пожалуйста, дёргай за методы. У тебя изнутри модуля переменная, естественно, доступна полным образом.

Цитата:
Более того, в случае с read-only record её методы вообще не имеют смысла, ведь они не могут сменить состояние своего же объекта.

Read-only методы имеют. Ну, в твоём примере This и Length сделай на IN.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 27 Май, 2016 07:03 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Вот именно, здесь объект это переменная, а не мой объект со всем его содержимым. Так же, как в ситуации с readonly указателем.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 27 Май, 2016 07:06 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Илья Ермаков писал(а):
Read-only методы имеют. Ну, в твоём примере This и Length сделай на IN.

Какой смысл, если никто ничего не добавит? :) А если сделать полный экспорт, то затереть список можно простым присвоением objList :=...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 27 Май, 2016 19:41 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Почему никто ничего не добавит?

Код:
MODULE MyMod;

   VAR
     listOfSomething-: Lists.List;

   PROCEDURE RegisterSomething (....)
      всякие проверки, действия...
      и тут спокойно вызываем методы на изменение listOfSomething
   END

END MyMod.


Ты выставил переменную на чтение - все смогут только читать, используя методы IN.
А ты изнутри модуля сможешь менять. Обеспечивая свою какую-то семантику, из которой только часть - модификация этой переменной.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 27 Май, 2016 21:58 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
А вызов связанной процедуры - это "изнутри модуля"?

А что будет после расширения записи? Где-то есть переменная с типом базовой записи, а в качестве значения в неё уложили расширенную запись. Сможет ли фактическая запись вызывать внутри себя процедуры базовой записи?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 08:56 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Что-то не нравится мне эта дискуссия.

Во-первых, нужен явный пример.

Во-вторых, система контроля в КП неплохо продумана, и вот так нахрапом что-то там менять -- лично я решительно протестую.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 12:19 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Valery Solovey писал(а):
А вызов связанной процедуры - это "изнутри модуля"?


Ну Вы изнутри своего модуля имеете полный доступ к переменной, которая экспортирована у Вас только для чтения!
Соответственно, можете вызывать её методы на изменение спокойно.

Цитата:
А что будет после расширения записи? Где-то есть переменная с типом базовой записи, а в качестве значения в неё уложили расширенную запись. Сможет ли фактическая запись вызывать внутри себя процедуры базовой записи?


Так расширенную запись Вы не уложите в качестве значения!
Расширенные могут адресоваться только по указателю либо по ссылке.

И из методов расширенной, где (VAR self), Вы сможете вызвать методы на изменение базовой.
А из методов, где (IN) - не сможете.

Всё нормально :)
Вложение:
sticker.png
sticker.png [ 63.35 КБ | Просмотров: 11108 ]


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 12:37 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Илья Ермаков писал(а):
Так расширенную запись Вы не уложите в качестве значения!
Расширенные могут адресоваться только по указателю либо по ссылке.
Запросто уложу -- в параметр.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 12:43 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Илья Ермаков писал(а):
И из методов расширенной, где (VAR self), Вы сможете вызвать методы на изменение базовой.
Стоит напомнить, что это средство называется supercall и в КП помечено на удаление из языка.

Сущность расширенной записи -- в незнании, с которым расширением мы работаем.

Если мы это знаем, то знаем и модуль, где нужный метод прописан.
А, значит, нет нужды прописывать его как метод, а достаточно -- как простую процедуру, и вызывать соответственно.

Тут мы упираемся в вопросы грамотного архитектурирования.

***

Сильно беспокоит в этой мутной дискуссии, что фокусы с переопределением семантики могут мотивироваться аргументами, опирающимися на "плохие практики".


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 14:01 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Info21 писал(а):
Илья Ермаков писал(а):
Так расширенную запись Вы не уложите в качестве значения!
Расширенные могут адресоваться только по указателю либо по ссылке.
Запросто уложу -- в параметр.


Ну так я и указал - адресоваться по ссылке.
Но не укладываться в переменную.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 18:26 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Info21 писал(а):
Сильно беспокоит в этой мутной дискуссии, что фокусы с переопределением семантики могут мотивироваться аргументами, опирающимися на "плохие практики".

Дискуссия начиналась конкретная относительно подсистемы Ypk. И дело не в supercall, а в том, что нельзя теперь переменную, экспортированную только для чтения, передавать в VAR параметр, где бы он не стоял, так как компилятор при этом теряет контроль над нетронутостью объекта во время компиляции.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 18:55 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Код:
MODULE PrivTest0;

   TYPE
      MyGlobalList* = LIMITED RECORD
         root, last: MyItem
      END;
      
      MyItem* = POINTER TO ABSTRACT RECORD
         next-: MyItem;
      END;
      
   VAR list-: MyGlobalList;
   
   PROCEDURE (VAR l: MyGlobalList) Add*(i: MyItem), NEW;
   BEGIN
      ASSERT(i # NIL, 20);
      IF l.last = NIL THEN
         l.root := i;
         l.last := i
      ELSE
         l.last.next := i;
         l.last := i
      END;
   END Add;
   
   PROCEDURE (VAR l: MyGlobalList) First*(): MyItem, NEW;
   BEGIN
      RETURN l.root
   END First;
END PrivTest0.


Код:
MODULE PrivTest1;

   IMPORT PrivTest0;
   
   TYPE
      MyItem = POINTER TO RECORD(PrivTest0.MyItem) END;
      
   PROCEDURE DoDo;
      VAR x: PrivTest0.MyItem;
   BEGIN
      x:=PrivTest0.list.First();
      WHILE x#NIL DO
         WITH x: MyItem DO
            (* пщ пщ *)
         ELSE END;
         x:=x.next;
      END;
   END DoDo;
   
   PROCEDURE Do*;
      VAR i: MyItem;
   BEGIN
      NEW(i);
      PrivTest0.list.Add(i);
      NEW(i);
      PrivTest0.list.Add(i);
      DoDo;
   END Do;
   
END PrivTest1.

(!)PrivTest1.Do


Суть задачи, которую теперь запрещено решать.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 19:14 
Администратор

Зарегистрирован: Вторник, 15 Ноябрь, 2005 01:14
Сообщения: 4695
Откуда: Россия, Орёл
Иван Денисов писал(а):
Дискуссия начиналась конкретная относительно подсистемы Ypk. И дело не в supercall, а в том, что нельзя теперь переменную, экспортированную только для чтения, передавать в VAR параметр, где бы он не стоял, так как компилятор при этом теряет контроль над нетронутостью объекта во время компиляции.

Иван, проблема не в Ypk, а в изменении семантики. Именно в том, что "нельзя теперь". Меняется же не тестовый академический компилятор, а промышленный инструмент, который любят, в том числе, за его устойчивость во времени. Это же не PHP.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 20:08 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Пётр Кушнир писал(а):
Суть задачи, которую теперь запрещено решать.

Илья предлагает разумным образом отказаться от представления этих функций как методов для таких случаев.
Код:
MODULE PrivTest0;

   TYPE
   MyGlobalList* = LIMITED RECORD
      root, last: MyItem
   END;

   MyItem* = POINTER TO ABSTRACT RECORD
      next-: MyItem;
   END;

   VAR list: MyGlobalList;

   PROCEDURE Add*(i: MyItem);
   BEGIN
      ASSERT(i # NIL, 20);
      IF list.last = NIL THEN
         list.root := i;
         list.last := i
      ELSE
         list.last.next := i;
         list.last := i
      END;
   END Add;

   PROCEDURE First*(): MyItem;
   BEGIN
   RETURN list.root
   END First;

END PrivTest0.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 20:33 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 3774
Борис Рюмшин писал(а):
Иван, проблема не в Ypk, а в изменении семантики. Именно в том, что "нельзя теперь".
Существуют сомнения, что возможность передать переменную только для чтения как VAR параметр - это баг, что мол может просто существовать разная трактовка read-only параметров.

Однако все согласятся, что многие проверки безопасности данных в коде КП выполняются до компиляции. Так вот этот баг не позволял проверке полностью проходить. Так как, если переменная передается в виде VAR, то дальше уже требования к неизменности невозможно проверить. Так как формально это ведь будет уже не read-only переменная. Так что этот фикс очень правильный. Это всего одна строчка в компиляторе:
http://redmine.blackboxframework.org/pr ... a7ed/diff/
Но она делает проверку сохранности данных до компиляции корректной.

Борис Рюмшин писал(а):
Меняется же не тестовый академический компилятор, а промышленный инструмент, который любят, в том числе, за его устойчивость во времени. Это же не PHP.
Это изменение сделает разработку только безопаснее. Ну и так как достаточно строгие требования, то исправить баг надо даже не смотря на то, что его наличие используется.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 21:12 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2662
Откуда: Россия, Ярославль
Иван Денисов писал(а):
Пётр Кушнир писал(а):
Суть задачи, которую теперь запрещено решать.

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

Мы тут все знаем, как сделать иначе. Вопрос, почему нельзя сделать так?
Вообще, я не уверен, что корректно относиться к receiver как к formal parameter. Параметр может быть у любой процедуры, а вот ресивер только у метода, который описан всегда рядом с типом, то есть всегда имеет доступ даже к скрытым переменным. И действительно, ресивер может быть объявлен как IN или VAR что гарантирует возможность контроля доступа к полям рекорда. Но этот IN/VAR это внутренние особенности поведения объекта. И хотя раньше это было сломано, хорошо, что сейчас починили.

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

То есть, я не понимаю, почему все тут решили, что доступ к рекорду извне и доступ из метода это одно и то же. Только потому, что увидели в компиляторе переход от rec.Method() к Method(rec)?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 28 Май, 2016 22:35 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
В Активном Обероне нельзя передать как VAR параметр импортированную сущность, если она экспортируется только для чтения. Её можно передать или по значению или как CONST.
Но методы у переменной-объекта, экспортированной только для чтения вызывать можно.


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

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


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

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


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

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