Вход:  Пароль:  
FreeSource: AltLinux/Sisyphus/Alterator/objects ...
Free Source | Каталог | Изменения | НовыеКомментарии | Пользователи | Регистрация |
Это старая версия AltLinux/Sisyphus/Alterator/objects за 2005-09-22 15:16:12..

Объектная система alterator.


В текущей нестабильной ветке alterator произошло большое изменение, там внедрены объекты. Зачем это нужно? Нужно это для того чтобы поддерживать код alterator было легче, чтобы убрать старые хаки, уменьшить количество cond и case, затрудняющее чтение. Что это такое? Читайте далее ....

Меченные функции


В Scheme, как во всяком уважающем себя функциональном языке, возможно построить структуру данных «пара» не пользуясь встроенными типами данных, а прямо на функциях. Например, это можно сделать так:

Однако всё не так хорошо как хотелось бы. Пользуясь только одними функциями невозможно сделать предикат pair?, то есть функцию, которая получив на вход некий объект, выдаёт истина только в случае если этот объект определённая выше структура «пара». Почему? Да очень просто. Вы не можете различать процедуры между собой. Ибо единственный способ различить подобные процедуры, это только запускать их, но результатом запуска может быть что угодно, включая попадание в вечный цикл. Говоря умнее, мы можем построить только полухарактеристическую функцию для множества пар.


Отсюда мораль, что требуется со стороны языка дополнительный способ «пометить» процедуры. Тогда мы могли бы гарантированно различать разные классы процедур между собой. Большинство реализаций Scheme поддерживают данный приём в том или ином виде.


Итак появляются первые две процедуры нашей объектной системы:


Пример:


Ура! Теперь мы можем различать между собой процедуры, чем это хорошо для нас – увидите чуть позже.

Объекты – это замыкания для бедных


Эта цитата принадлежит Norman Adams и сейчас вы убедитесь насколько это верно ;)


Любая созданная процедура, запоминает своё окружение, вместе со всеми определёнными там переменными и другими функциями. При этом запоминает настолько хорошо, что: куда бы далее вы не передавали эту процедуру, она будет работать именно с тем окружением в котором родилась (подобно тому как циплята, кого увидят первым, вылупившись из яйца, того и считают мамой), данные окружении будут существовать до тех пор, пока они требуются хотя бы одной процедуре. Например:



Здесь, функция +three, появившись запомнила, что x это 3, и при всех последующих запусках будет работать именно с этим значением, даже если мы явно зададим x в значение 10.


Итак, у нас есть «память», а если есть «память», значит можно сделать функции с состоянием, иначе говоря объекты.
Вот например простейший объект, изображающий точку на плоскости:


Вот теперь ясно видно, что имея замечательное свойство «памяти», можно создавать то что в других языках программирования называют объектами, то есть совокупность данных и методов, работающих с этими данными. То как именно строить объекты – никто вас не ограничивает, поэтому существует множество вариантов объектных систем для Scheme. Система объектов Alterator похожа на объектные системы T и YASOS.

Методы или сообщения


Работают с объектами, как правило, одним из двумя способами: явно обращаясь в методам или данным или передавая объекту сообщение. Эти способы совершенно равноценны. Просто в одном языке удобнее вызвать метод:

В другом, послать объекту сообщение с желанием выполнить метод:

Как догадываетесь, в LISP принято использовать второй способ.

Простые объекты


Основной компонент объектной системы – диспечер методов, создаётся процедурой object.
Данные для диспечера методов, создаются благодаря свойству замыкания, когда объект создаётся при помощи некоторой функции – коструктора. Создаваемому диспечеру в качестве параметра передаётся метка, которую потом можно изучать с помощью процедур instance-of и is-a?.
Создадим объект точки на плоскости:

В описании мы задали диспечеру метку <point> и перечислили методы. В описании каждого метода перечисляются его имя и параметры, первый параметр, обязательный – self. Это ссылка диспечера самого на себя – очень полезное свойство. Данный параметр всегда передаётся неявно, поэтому при посылке сообщений его не надо указывать.


Созданный диспечер бесполезно запускать неспосредственно, он ведь занимается только разбором какой метод надо вызвать и как. Если мы хотим сделать «запускаемый» объект, то надо воспользоваться процедурой callable. В результате применения callable, мы получим процедуру, которая будет заниматься передачей сообщений диспечеру и запуском требуемых методов. Метка у этой процедуры будет в точности такая же, как была у объекта


Если вы хотите всегда работать с «вызываемыми» объектами, то можно включить вызов callable прямо в конструктор:

Составные объекты


Можно усложнять «маршрутизацию сообщений», тем самым создавая то, что в других языках программирования называют «наследованием» и «иерархией объектов».


Для комбинирования объектов используется процедура join. В результате применения join к диспечерам, получается составной диспечер. Таким образом «наследование» и «конструирование» объектов – отдельные операции, благодаря чему, можно «наследовать» влюбых сочетаниях и в любом направлении.


Обратите внимение, что join может работать только с диспечерами. Вызываемые объекты объединять уже нельзя.


Создадим объект точки в пространстве:


Обратите внимание, что первым параметром к join также как и к object идёт «метка». Также стоит заметить что меня никто не ограничивает в выборе метки. Если я уверен, что point-3d потом распознается и будет работать так же как и обычная точка, могу ему дать ту же самую метку.


Когда идёт поиск обработчика сообщения, то компоненты комбинированного диспечера просматриваются последовательно. Поэтому можно перехватывать сообщения и эмулировать эффект, переопределения функций.


Ну и наконец, последний способ маршрутизации: можно определить точку перехвата всех необработанных сообщений. То есть, если в диспечер приходит сообщение, и никто не найден, то данный специальный метод получит управление. Понятно, что нет смысла в комбинированном объекте в первом же компоненте делать такой перехват – до других компонент сообщения просто не будут доходить.


Оформляется такой обработчик как метод с именем совпадающем с меткой объекта (следовательно он может быть только один, что вполне логично).


Создадим объект «пустой аттрибут». Если у него спросить имя аттрибута, то он его вернёт, а все остальные сообщения интерпретируются как попытки задать данному аттрибуту значение и в результате возвращается объект «аттрибут со значением». Последний также воспринимает сообщения на предмет получения его имени и значения, а все остальные сообщения интерпретирует как попытки добавить ещё одно значение, то есть в результате возвращается аттрибут с расширенным значением.
Пример:


Описываются эти объекты очень и очень просто:


Ну вот и всё. Объектная система простая – как и всё в Scheme.



 
Файлов нет. [Показать файлы/форму]
Комментариев нет. [Показать комментарии/форму]