Добавление методов в hype3 класс пост-фактум
By exs. Sunday, 10. August 2008, 12:55:06
Как можно добавить новые методы в уже скомпилированный класс в ООП-расширении hype3.
Зачем это может понадобится? Реальная ситуация при работе с WFL.
В классе CWindow есть setText ( a u -- ), но нет метода setStrText ( s -- ). Часто бывает что строки создаются динамически и хочется вместо развесистого
CButton NewObj -> b
S" строка " S" какая-то " " {s}{s}" DUP STR@ b => setText STRFREE
писать
CButton NewObj -> b
S" строка " S" какая-то " " {s}{s}" b => setStrText
И аналогично для всех классов которые наследуются от CWindow.
Но. Сделать это "в лоб" не модифицируя код CWindow получится. Если отнаследоваться от CWindow и добавить там нужные методы -- другие классы-наследники CWindow этого не заметят и будут работать по старому. Можно отнаследовать CWindow от CWindow до загрузки классов контролов и тогда они возьмут новый CWindow с нужными методами, но это неудобно тем что надо контролировать порядок загрузки библиотек. Как же быть?
Рецепт прост
MODULE: HYPE EXPORT : +METHODS ( ta -- ) GET-CURRENT PREVIOUS-CURRENT ! ( ta ) METHODS ; ;MODULEи далее (в любое время после загрузки и компиляции CWindow, СButton etc)
CWindow +METHODS \ str is STRFREEd : setStrText ( str -- ) DUP STRA 0 WM_SETTEXT sendMessage DROP STRFREE ; ;CLASS(Можно было бы ещё короче : setStrText DUP STR@ setText STRFREE ;, но это двойное выделение памяти и копирование).
И теперь все наследники CWindow понимают метод setStrText!
Дело в том что методы в hype3 это обычные слова которые создаются в wordlist'е ассоциированном с классом. Ничто не мешает добавлять слова в этот список в любое время, например после компиляции класса. Можно даже добавлять методы в рантайме. Новые методы имеют те же "права" что и старые, т.е. могут вызывать другие методы, использовать данные класса итп. Немного напоминает Javascript-овое
Object.prototype.new_func = function() { ... };Реализация получилась простой благодаря хорошей факторизации либы hype3.f. Внутреннее слово METHODS устанавливает список слов-методов текущим списком компиляции. Первая строка по сохранению CURRENT взята из определения CLASS -- по-хорошему её надо было бы выделить в отдельное слово.Добавлять данные таким способом нельзя т.к. данные должны не просто разрешаться по имени, но и иметь своё место в экземпляре класса. Впрочем можно модифицировать классовую переменную -- "размер экземпляра", но это требует осторожного отношения при использовании.





How to use Quote function: