Я думаю многие обрадуются, если я сообщу, что есть возможность работать с любыми переменными любых классов!
Независимо от атрибута 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!
Заметь, что для нарушения этого запрета в первом случае мы воспользовались простым стандартным способом! Второй случай (получение указателя на список), согласен, ближе уже к нестандартным способам получения данных!