По мотивам - Коротко. Сделал чудную штуку - переопределение слов
Вот такое сделал:
Раньше массивы не печатались, а теперь печатаются.
А можно ещё сделать так:
Теперь ещё и объекты "печатаются".
Виртуальность, без виртуальности. REDEFINITION'ы "нанизываются" друг на друга как "обработчики прерываний", ну или как "хуки".
Один REDEFINITION декорирует другой.
Там правда с порядком вызова есть "тонкости" - СНАЧАЛА надо REDEFINITION для IsObject, а ТОЛЬКО ПОТОМ - для IsArray.
Чтобы рекурсия работала правильно.
А если нужна "реальная виртуальность", то можно вклинить и виртуальность.
Позже напишу как.
Ну в общих словах пока так:
Зачем всё это?
Это всё нужно для доопределения грамматики и трансформирования предметной области.
Там где невозможно менять "проектные классы".
Например для тестировщиков.
Ну а о том как менять проектные классы (типа делать АОП - Агентно-ориентированный подход и Аспектно-ориентированное программирование) я напишу позже.
Вообще говоря все эти REDEFINITION'ы и нужны для того, чтобы ДООПРЕДЕЛЯТЬ "аспекты". Которые не УКЛАДЫВАЮТСЯ в "сквозную иерархию" проектных классов.
Они - СБОКУ, от иерархии наследования.
Ну и понятно, что это всё не для "конечного пользователя", а лишь для тех кто хочет и МОЖЕТ доопределять грамматику.
Ремарка:
strings:Cat - складывает строки в массиве
strings:CatSep - складывает строки в массиве через разделитель
@SELF DO - рекурсивно вызывает "себя же"
CompileValue - компилирует ссылку на слово
Всё описанное реализует собой парадигму "контрольных точек".
(+) О тестах и специально оборудованных "контрольных точках"
(+) Коротко. Ни о чём. Инверсия зависимостей
(+) Коротко. Продолжение про инверсию зависимостей
(+) Коротко. О блоге, стиле написания статей и ведении полемики
(+) Депрессия. Или превратности hResult и прочих ErrorCode
Вот такое сделал:
REDEFINITION STRING FUNCTION ToPrintable IN aValue if ( aValue IsArray ) then ( [ '[ ' for aValue ( @SELF DO ) ' ]' ] ' ' strings:CatSep >>> Result ) else ( aValue inherited >>> Result ) ; // ToPrintable
Раньше массивы не печатались, а теперь печатаются.
А можно ещё сделать так:
REDEFINITION STRING FUNCTION ToPrintable IN aValue if ( aValue IsObject ) then ( if ( aValue IS class:TComponent ) then ( [ aValue pop:Component:Name ':' aValue pop:object:ClassName ] strings:Cat >>> Result ) else ( aValue pop:object:ClassName >>> Result ) ) else ( aValue inherited >>> Result ) ; // ToPrintable
Теперь ещё и объекты "печатаются".
Виртуальность, без виртуальности. REDEFINITION'ы "нанизываются" друг на друга как "обработчики прерываний", ну или как "хуки".
Один REDEFINITION декорирует другой.
Там правда с порядком вызова есть "тонкости" - СНАЧАЛА надо REDEFINITION для IsObject, а ТОЛЬКО ПОТОМ - для IsArray.
Чтобы рекурсия работала правильно.
А если нужна "реальная виртуальность", то можно вклинить и виртуальность.
Позже напишу как.
Ну в общих словах пока так:
REDEFINITION STRING FUNCTION ToPrintable IN aValue PUBLIC STATIC VAR g_ToPrintable = inherited // - тут запоминаем ссылку на inherited aValue g_ToPrintable DO >>> Result // - тут выполняем то, что лежит в ссылке // Ну и понятно, что "позже" эту ссылку можно переопределить // Таким образом: // ... в ДРУГОМ месте кода где-то ... // Пишем следующее: STRING FUNCTION ClassToPrintable IN aValue VOID IMMEDIATE OPERATOR CompileCallToPrintable ToPrintable :: g_ToPrintable CompileValue @ DO CompileValue // - тут компилируем вызов по ссылке того, что лежит в g_ToPrintable ; // CompileCallToPrintable if ( aValue IsObject ) then ( if ( aValue IS class:TComponent ) then ( [ aValue pop:Component:Name ':' aValue pop:object:ClassName ] strings:Cat >>> Result ) else ( aValue pop:object:ClassName >>> Result ) ) else ( aValue CompileCallToPrintable >>> Result ) ; // ClassToPrintable ToPrintable :: g_ToPrintable := ClassToPrintable // - тут переопределили ссылку // Ну и дальше опять же - рекурсивно по цепочке // Вот так: STRING FUNCTION ArrayToPrintable IN aValue if ( aValue IsArray ) then ( [ '[ ' for aValue ( @SELF DO ) ' ]' ] ' ' strings:CatSep >>> Result ) else ( aValue CompileCallToPrintable >>> Result ) ; // ArrayToPrintable ToPrintable :: g_ToPrintable := ArrayToPrintable // - тут переопределили ссылку ; // ToPrintable
Зачем всё это?
Это всё нужно для доопределения грамматики и трансформирования предметной области.
Там где невозможно менять "проектные классы".
Например для тестировщиков.
Ну а о том как менять проектные классы (типа делать АОП - Агентно-ориентированный подход и Аспектно-ориентированное программирование) я напишу позже.
Вообще говоря все эти REDEFINITION'ы и нужны для того, чтобы ДООПРЕДЕЛЯТЬ "аспекты". Которые не УКЛАДЫВАЮТСЯ в "сквозную иерархию" проектных классов.
Они - СБОКУ, от иерархии наследования.
Ну и понятно, что это всё не для "конечного пользователя", а лишь для тех кто хочет и МОЖЕТ доопределять грамматику.
Ремарка:
strings:Cat - складывает строки в массиве
strings:CatSep - складывает строки в массиве через разделитель
@SELF DO - рекурсивно вызывает "себя же"
CompileValue - компилирует ссылку на слово
Всё описанное реализует собой парадигму "контрольных точек".
(+) О тестах и специально оборудованных "контрольных точках"
(+) Коротко. Ни о чём. Инверсия зависимостей
(+) Коротко. Продолжение про инверсию зависимостей
(+) Коротко. О блоге, стиле написания статей и ведении полемики
(+) Депрессия. Или превратности hResult и прочих ErrorCode
Комментариев нет:
Отправить комментарий