По мотивам - Коротко. Сделал чудную штуку - переопределение слов
Вот такое сделал:
Раньше массивы не печатались, а теперь печатаются.
А можно ещё сделать так:
Теперь ещё и объекты "печатаются".
Виртуальность, без виртуальности. 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
Комментариев нет:
Отправить комментарий