Некоторые особенности при работе с CLASS`ами

Я думаю многие обрадуются, если я сообщу, что есть возможность работать с любыми переменными любых классов!
Независимо от атрибута Private или Protected!

Особенно это актуально при работе с ABC-шаблонами, чьи классы организованы не самым лучшим образом! Теперь, для доступа к Private-переменным, нет необходимости в модификации исходников.

Все очень просто решается использованием функций What/Who/Where!

Кстати, для этого мы воспользуемся сразу двумя ошибками (или недоработками) разработчиков Клариона!

Первая глобальная недоработка — описание классов храниться точно в такой же структуре, как и описание групп. А там просто не предусмотрены подобные «классовые» атрибуты — Private/Protect и пр. Т.е. эти атрибуты действуют ТОЛЬКО для компилятора!

Вторая ошибка — недоработка функций What/Who/Where, основанная на первой ошибке. Кстати, не пытайтесь с помощью What() получить доступ к полям-массивам группы!!! GPF в 100% случаев!!!

Итак! Например, есть класс:

QueueType  QUEUE,TYPE
Name         &STRING
Desc         &STRING
Id           LONG
           END

OneClass   Class...
Field1       BYTE                ! Поле N1
Field2       &STRING             ! Поле N2
PField1      LONG,PRIVATE        ! Поле N3
NameQue      &QueueType,PRIVATE  ! Поле N4
             ... ! Методы
           End

В секции данных своей программы заводим необходимые переменные:

MyClass    OneClass

MyField    ANY
TstGrp     GROUP
MyFields     &QueueType
           END
OverGrp    ULONG,OVER(TstGrp)

Предположим, что в своей программе нам очень надо получить прямой доступ к полю MyClass.PField1. Для этого получаем указатель на него:

  MyField &= What(MyClass,3)      ! Указатель на поле N3

Теперь можно или читать это поле — Message(MyField), или изменять его — MyField = 10! Используя Who(), можно находить нужные поля по именам.

Так-же можно получить прямой доступ и к защищенным спискам. Правда, несколько сложнее. Например надо напрямую работать со списком MyClass.NameQue. Для получения указателя на него придется несколько повозиться:

  OverGrp = Address(What(MyClass,4)) ! Поле N4
  Peek(OverGrp,OverGrp)
  Peek(OverGrp+4,OverGrp)
  Peek(OverGrp,OverGrp)

Все! Теперь TstGrp.MyFields — указатель на оригинальный список класса MyClass! С ним можно работать как с обычным списком:

  Recs# = Records(TstGrp.MyFields)
  TstGrp.MyFields.Id = 10
  Get(TstGrp.MyFields,+TstGrp.MyFields.Id)
  Message(TstGrp.MyFields.Name)
  if ~TstGrp.MyFields.Desc
     TstGrp.MyFields.Desc = 'Наш комментарий'
     Put(TstGrp.MyFields)
  .

Вообщем, в таком вот разрезе!

Успехов!

P.S. 2Цигуро: Ну как? Это баг или «фича»? Если «фича», то как она соотносится со всеми канонами объектного программирования? Да и с той же докой по Кларион, где декларируется полная защищенность переменных типа Private/Protect!

Заметь, что для нарушения этого запрета в первом случае мы воспользовались простым стандартным способом! Второй случай (получение указателя на список), согласен, ближе уже к нестандартным способам получения данных!