Smalltalk по-русски
четверг, Апрель 28, 2005
Будущее IBM Instantinations' VisualAge Smalltalk

IBM объявила о том, что 30 апреля 2006 года прекращает поддержку IBM VisualAge Smalltalk.

Однако, развитие и поддержка самого VA Smalltalk на этом не заканчивается. По соглашению с IBM далнейшим развитием, поддержкой и продвижением будет заниматься Instantiations, Inc.

Instantinations обещает, что Instantiations' VisualAge Smalltalk 7.0 появится уже в 3-м квартале этого года.

В планах по развитию:

  • В 7.0: интегрировать в среду VA Assist, Refactoring Browser, ENVY Extensions, включить в поставку WidgetKit/Controls и GF/ST;
  • В 7.5: полная поддержка ANSI Smalltalk, модернизация IDE, поддержка новых Windows-виджетов, начало расширения поддержки веб-сервисов;
  • В 8.0: поддержка Longhorn, 64-битные ВМ, дальнейшее расширение поддержки веб-сервисов, введение пространств имён.

Ожидаемая стоимость - $6'995 на разработчика с 1 годичной поддержкой и апгрейдами. Пользователи версий IBM VA Smalltalk имеющие поддержку смогут обновится до Instantiations' VA Smalltalk за $1'495. Пользователи не имеющие поддержки, а так же пользователи конкурирующих диалектов смогут перейти на VAST 7 за $1'995.

Ярлыки:

вторник, Апрель 26, 2005
[VW] Знаете ли Вы, что такое Ephemeron?
Проблемы "простого" сборщика мусора

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

Самый распространённый пример такой задачи - хранение подписчиков на события объектов. Первоначально в ST использовалась очень простая схема, когда для добавления подписчиков используется сообщение #addDependent: с аргументом - подписчиком на события. Сейчас схема усложнилась - появилась возможность подписываться не на все события подряд, а только на те, которые интересуют, но принципиально ничего не поменялось - есть объект публикующий события и объекты-подписчики обрабатывающие события. Первое, что приходит в голову - завести переменную для хранения коллекции объектов-подписчиков. С этой схемой особых проблем нет. Коллекция объектов умрёт вместе с объектом публикующим события, а значит объекты-подписчики не будут удерживаться дольше чем нужно. Именно так и устроен класс Model. Однако, в ST подписаться на некие события можно не только у модели, а у любого объекта (простейший пример - WeakArray уведомляет своих подписчиков о смерти хранимых в нём объектов). Тут можно либо попробовать заводить переменную объекта для подписчиков в каждом классе, который может публиковать события, либо разрешить проблему сразу для всей системы задействовав класс Object. Однако, заводить переменную объекта для хранения подписчиков в классе Object не только нецелесообразно, но и невозможно в текущих реализациях виртуальных машин (ВМ).

Раз нельзя завести переменную, то прийдётся идти другим путём. А именно, заведём глобальный словарь где ключом будет объект публикующий события, а связанным с ключом значением будет коллекция подписчиков. Такие словари, где ключ это некий объект, а значение это присоединённое к объекту свойство, зачастую называют реестрами. Решение это вроде бы универсальное, но реестр то глобальный.

Иллюстрация словаря на сильных ссылках
А значит живёт он вечно, и, вместе с ним будут удерживаться и все объекты, и публикующие события и подписавшиеся на них. И если от событий не отписываться, то возникнет утечка памяти. О том, к каким проблемам приводила подобная схема говорит тот факт, что в VW для инспектирования подобного словаря существует отдельный пункт меню "Browse -> Inspect -> DependentsFields" и все рекомендации по борьбе с утечками советуют в первую очередь проверить именно этот глобальный словарь.

Для борьбы с такими ситуациями и придумали слабые ссылки (weak references). Попробуем задействовать слабые ссылки для реализации нашего реестра. Что же получится, если для хранения ключей словаря использовать слабые ссылки?

Иллюстрация словаря с ключами на слабых ссылках
На первый взгляд может показаться, что это то, что нужно. Как только объект-ключ станет мусором, он будет уничтожен, а вслед за этим будет освобождена и коллекция подписчиков. Однако, если из объектов-подписчиков будет сильная ссылка на объект-ключ, то возникнет всё та же утечка памяти.

Попытка использовать для слабые ссылки для хранения значений еще более нелепа.

Иллюстрация словаря со значениями на слабых ссылках
Ведь получается, что если где-то специально не удерживать подписчиков, то они будут собраны сборщиком мусора, хотя по логике работы программы они всё еще должны бы реагировать на события в публикующем объекте.

Получается, что нужен некий симбиоз двух подходов.

Иллюстрация словаря на эфемеронах
А именно, ссылка на ключ слабая. Ссылка же на значение должна быть сильной, но только до тех пор, пока есть строгие ссылки на ключ "со стороны", то есть, не идущие от самого словаря. После того, как ключ может стать "мусором" должно быть освобождено и значение. Именно такое поведение обеспечивают обычные переменные объекта - значение переменной освобождается по уничтожении объекта в котором это значение хранится. Подобное поведение и обеспечивают эфемероны (ephemerons).

Суть эфемеронов

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

Эфемероны были придуманы Георгом Босвортом (George Bosworth) из Digitalk для Visual Smalltalk Enterpraise и описаны Барри Хэесом (см. "Ephemerons: a new finalization mechanism; Barry Hayes; Proceedings of the 1997 ACM SIGPLAN conference on Object-oriented programming systems, languages and applications, 1997, Pages 176 - 183"). В VW эфемероны реализованы Барри Хэесом и Элиотом Мирэндой.

Помимо VW существует реализация эфемеронов для Squeak (упрощенный вариант, когда все ссылки просто об-nil-яются при исчезновении ссылок на ключ); эфемероны есть в GNU Smalltalk начиная с версии 2; эфемероны используются в XEmacs; очень похожий механизм, называемый "key/value weak pointers", существует в Haskell.

Эфемероны в VW

Для начала напомню, что в VW могут существовать классы, имеющие различную природу. Тип класса задаётся при его создании параметром indexedType:. Допустимые значения параметра: #none, #objects, #bytes, #immediate, #weak и #ephemeron. По-умолчанию тип проставляется в #none, и, поскольку прикладным программистам нет нужды создавать классы прочих типов, то описание значения этих типов будет дано другим разом. Сейчас же остановимся на типе #ephemeron.

Класс, создаваемый с indexedType: выставленным в #ephemeron, должен содержать минимум одну переменную экземпляра. Допустимо, что это переменная унаследованная от какого либо родительского класса. Такой класс должен быть унаследован от класса с типом #none и подклассы должны быть только типа #ephemeron.

Самая первая переменная экземпляра по-особому обрабатывается сборщиком мусора. Именно она и считается ключем из описания выше. То есть, если на объект в первой переменной экземпляра нет ссылок, то все прочие переменные эфемерона сборщик мусора не трассирует. Это позволяет обнаружить изолированные графы объектов. То есть графы объектов, в которых корнями являются только эфемероны. После нахождения всех таких эфемеронов сборщик мусора ложит их все в очередь для финализации, а затем трассирует все поля эфемеронов, что бы объекты в эфемеронах оставались живы.

Эфемероны и финализация в VW

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

Эфемероны в VW поддерживают пообъектную финализацию. После того, как сборщик мусора находит живые эфемероны у которых на ключ (первую по порядку переменную) нет больше ссылок, этим эфемеронам посылается сообщение #mourn. Если на эфемерон нет ссылок, то сообщение #mourn ему не посылается. В VW уже существуют стандартные реализации классов с "indexedType: #ephemeron", которые содержат ряд методов управляющих финализацией. Это WeakKeyAssociation и его потомок класс Ephemeron.

Объекты класса WeakKeyAssociation после выполнения метода #mourn начинают возвращать false на сообщение #isActiveEphemeron. Если такому объекту послать сообщение #isActiveEphemeron: true, то процедура финализации может быть запущена повторно. Метод #mourn в классе WeakKeyAssociation просто проставляет nil в полях "ключ" и "значение".

Поведение потомка WeakKeyAssociation, класса Ephemeron, более сложное. Оно позволяет, кроме выполнения действий по очистке полей эфемерона, освободить так же и сам эфемерон. Одна из переменных экземпляра в классе Ephemeron - manager. По умолчанию, метод #mourn просто посылает менеджеру сообщение #mournKeyOf: self. Класс EphemeronDictionary это словарь, в котором в качестве ассоциаций используются эфемероны. При создании ассоциации в EphemeronDictionary, словарь создаёт эфемерон в котором менеджер это сам словарь. Таким образом, словарь может получить уведомление о том, что его эфемерон готов "умереть" через сообщение #mournKeyOf:. Сам словарь так же позволяет изменить менеджер у всех своих эфемеронов через сообщение #manager:. По-умолчанию, словарь просто удаляет ссылку на "умерший" эфемерон, позволяя сборщику мусора уничтожить граф объектов с эфемероном во главе. И так, чтобы обработать уведомление о том, что на ключ эфемерона больше нет ссылок есть несколько вариантов:

  • создать свой класс c "indexedType: #ephemeron" с процедурой #mourn;
  • создать подкласс класса Ephemeron и переопределить метод #mourn;
  • создать подкласс класса EphemeronDictionary и переопределить метод #mournKeyOf:;
  • создать свой класс с методом #mournKeyOf: и задать его в качестве менеджера в сам эфемерон или в словарь эфемеронов.
Обратите особое внимание, что сообщение #mourn будет послано только тому эфемерону на который есть сильные ссылки. Это сделано для того, чтобы избежать необходимости "оживлять" эфемероны. Именно по-этому, в VW эфемероны используются только опосредованно, через класс EphemeronDictionary.

Ярлыки:

суббота, Апрель 23, 2005
[VW] Полезняшки: StorePlugins

StorePlugins добавляет возможность получать уведомление о фактах загрузки/публикации пакетов в Store или выполнять определённые действия перед загрузкой/публикацией.

Сконфигурировать плагины можно через закладку 'Store Plugins', которая появляется если выбрать пакет в RB. Обратите внимание, что использовать это расширение можно только с той версией VW, которая указана в заголовке StorePlugins. На момент написания заметки в репозитории находилась версия предназначенная для работы с VW 7.2.1.

В состав StorePlugins уже включены несколько плагинов:

  • LintCheckPlugin - выполняет проверку Lint-ом перед публикацией пакета;
  • SignaturePlugin - создаёт подпись пакета и при загрузке проверяет эти подписи;
  • PrerequisiteCyclePlugin - проверяет отсутствие циклических зависимостей у публикуемых пакетов;
  • BlessingLevelPlugin - выдаёт предупреждение при загрузке пакета маркированого как нестабильный;
  • LoggingPlugin - логирует факты загрузки или публикации пакетов.

StorePlugins доступен в открытом репозитории.

Ярлыки:

четверг, Апрель 21, 2005
Dolphin 6 - IdeaSpace
Появилась первая информаци о будущем Dolphin 6. Посмотрите flash ролик (около 2,5Мб) демонстрирующий возможности IdeaSpace.

Ярлыки:

среда, Апрель 20, 2005
Находим публичный интерфейс класса во время выполнения

Иногда надо найти для класса все методы, вызываемые другими классами (но не самим собой). Чтобы не копаться с senders/impementors можно попробовать это сделать автоматом во время выполнения (с помощью MethodWrappers). Запускаем код и смотрим какие методы были вызваны.

Например я хочу узнать какие методы другие классы вызывают у ProductionOrder.

ProductionOrder
 extractInterfaceDuring: [testRunner runSuite: DomainTestSuite new].

Открывается окно со всеми методами которые другие классы вызывают у ProductionOrder во время запуска тестов

Если надо показывать также методы определенные в суперклассах, то можно сделать так:

ProductionOrder
    extractInterfaceUpTo: AbstractOrder
    during: [testRunner runSuite: DomainTestSuite new]

Пакет ExtractInterface находится в открытом репозитории. Перед загрузкой ExtractInterface загрузите пакет MethodWrapper .

Еще одно полезное применение. Например во время рефакторинга иерархии классов часто возникает вопрос насколько сильно класс связан со своими суперклассами. Можно ли его перенести в другую иерархию. Запускаем ExtractInterface и смотрим какие методы суперклассов реально используються.

понедельник, Апрель 18, 2005
1-е ежегодное соревнование программистов на Smalltalk

В анонсе о первом ежегодном соревновании программистов на Smalltalk проводимом STIC вкралась глупая опечатка. Регистрация не начнётся 1-го мая, а уже началась 1-го марта. Так что желающие могут уже регистрироваться.

Напомню, что регистрация заканчивается 13 мая в 18 часов EST (14 мая в 2 часа по московскому времени). 1-я фаза, продолжительностью 48 часов, начнётся в понедельник 16 мая в 9 часов утра EST (17 часов по московскому времени) и закончится в среду 18 мая в 9 часов утра EST (17 часов по московскому времени). Требования будут выложены на сайте STIC с началом первой фазы.

Если у вас есть вопросы, то возможно ответы вы найдёте в FAQ

Ярлыки:

пятница, Апрель 15, 2005
Ruby/Python on Smalltalk VM

Peter Suk проявил желание написать транслятор Ruby в байткоды Smalltalk VM. Как я понял, это пока только планы, конкретный проект не начат. Не понятно на байткоды какой ВМ будет ориентация в первую очередь (предполагаю - VisualWorks).

Что же ожидается от этого симбиоза:

У Ruby будет гораздо более быстрая среда выполнения (возможно ускорение в 30 раз); ВМ с инкрементальным и основанным на поколениях сборщиками мусора, которые настолько быстры, что даже если объекты создаются в бесконечном цикле, то программа продолжает работать; отличный отладчик, который позволяет изменять методы на лету и продолжать выполнение; окно "workspace" в котором можно выполнить любой кусок кода; визуальный инспектор объектов; мощный "Refactoring Browser"; индустриальная объектно-ориентированная БД (Gemstone) с возможностью определять методы объектов на Ruby; легко доступный метауровень, который позволит программистам на Ruby легко модифицировать язык (например, используя MethodWrappers можно легко реализовать Аспектно-ориентированный Ruby).

Хочу заметить, что 30 кратное ускорение не выглядит особенно фантастично. ВМ VW в 75 раз быстрее Ruby. Плюс быстрый сборщик мусора вместо счетчика ссылок могут дать подобную скорость. В качестве подтверждения можно привести PyCore - транслятор байткодов Python в байткоды VW. Даже первая версия показала значительное ускорение многих операций, это при том, что различий между Smalltalk и Ruby на много меньше, чем между Smalltalk и Python.

Кстати, из OO Richards Bench можно сделать вывод, что написание небольшой ВМ на С, а всей остальной системы на "основном" языке гораздо более перспективно даже с точки зрения времени выполнения. Так, динамическая ВМ (VW) всего в 2-3 раза медленнее статических ВМ, и намного (75 раз) быстрее систем где часть системы написана на одном "основном" языке с критическими по времени выполнения частями на С.

понедельник, Апрель 11, 2005
[Job] Работа в Transas (Санкт-Петербург)

Компании Transas, мировому лидеру в производстве программных систем для морского и авиационного транспорта, требуется разработчик в проект по разработке системы автоматизации развлекательных комплексов и ресторанов. Разработка ведется на VisualWorks Smalltalk. Применяется методология XP.

Обязанности: участие в создании системы на всех этапах, работа в команде из 4 человек. Требования: профессиональный опыт - от 3 лет; опыт разработки бизнес-систем, коллективной разработки. Владение методиками OOA/OOD/OOP; знакомство с процессами разработки ПО. Отличное владение одним из следующих языков: Smalltalk, Java, C#, С++, Ruby, Python. Знакомство со Smalltalk приветствуется. Знакомство с одной или более технологиями: COM, SQL и эксплуатация серверов, Web/HTML, сервера web-приложений, разработка UI, Macromedia Flash.

Контактное лицо: Андрей Мужиков <Andrey.Moujikov at transas.com>.

пятница, Апрель 08, 2005
[VW] Полезняшки: Teachable

Как известно, в Smalltalk объекты могут обрабатывать "нестандартые" сообщения - при получении сообщения для обработки которого нет метода будет вызван метод #doesNotUnderstand: (кратко - DNU). Эта способность часто используется для создания разного рода "прозрачных" прокси - для пересылки сообщений удалённым объектам, для ленивой загрузки объектов из БД, или для организации делегирования.

Еще одним вариантом использования перехвата неизвестных сообщений является создание "обучаемых" объектов. Например, объект может перехватывать сообщения с одним параметром, сохранять параметр и, затем, возвращать значение параметра в ответ на соответсвующее унарное сообщение. То есть, при получении сообщения parametr: anObject этот самый anObject будет сохранён в словаре в объекте и будет возвращен в ответ на сообщение parametr.

Класс Teachable является более продвинутой реализацией идеи обучаемых объектов. Его можно обучить отвечать на любое сообщение.

Пример обучения:

|teachable|
teachable := Teachable new.
teachable
    whenSend: #help return: 'ok';
    whenSend: #doit evaluate: [1 inspect];
    acceptSend: #noDebugger;
    whenSend: #negate: evaluate: [:num | num negated].
После обучения объект готов к использованию:
teachable help. вернёт строку 'ok'
teachable doit. откроет в инспекторе число 1
teachable noDebugger. Сообщение #noDebugger является допустимым,
    а его результат - сам обучаемый объект
teachable negate: 120 вернёт число -120

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

Для реализации такого поведения нужно всего 5 методов. Три обучающих:

whenSend: aSymbol evaluate: aBlock
  При получении сообщения с данным селектором 
  выполнить блок с параметрами полученного сообщения

  self learnings at: aSymbol put: aBlock

whenSend: aSymbol return: anObject
  В ответ на сообщение с данным селектором 
  вернуть указанный объект

  self learnings at: aSymbol put: (#return -> anObject)

acceptSend: aSymbol
  Сообщение с данным селектором является допустимым

  self whenSend: aSymbol return: self
Для ответа на "обученные" сообщения используется DNU:
learnings
  Возвращает словарь для хранения данных об обучении
 
  ^learnings ifNil: [learnings := Dictionary new]

doesNotUnderstand: aMessage
  Если объект не обучен такому сообщению, 
  то будет вызван стандартный метод DNU

  | learning |
  learning := self learnings 
      at: aMessage selector 
      ifAbsent:[ ^super doesNotUnderstand: aMessage ].
  ^learning class == Association
      ifTrue: [learning value]
      ifFalse: [learning valueWithArguments: aMessage arguments]
Всё!

Версия для VW находится в публичном Store-репозитории, и состоит из двух пакетов Teachable и Teachable Tests. Версия для Squeak находится в SqueakMap.

Ярлыки:

вторник, Апрель 05, 2005
Smalltalk/JVM - open source?

Компания Mission Software рассматривает возможность сделать продукт Smalltalk/JVM open source.

Ответы на часто задаваемые вопросы по Smalltalk/JVM можно прочитать по этой ссылке.

Ambrai Smalltalk 1.0.6 Beta

Ambrai Smalltalk 1.0.6 Beta3 доступна для скачивания. Ambrai Smalltalk - это диалект работающий исключительно под Mac OS X. О нововведениях можно прочитать в пресс-релизе.

Так же доступен новый учебник по разработке на Ambrai Smalltalk под Cocoa.

Популярные статьи
:: Smalltalk?!
:: Почему Smalltalk?
:: Great Leap Forward from Java to Smalltalk

Последние сообщения
:: Smalltalk и Все-Все-Все: Белка-Рыба наносит ответн...
:: Smalltalk и Все-Все-Все
:: [Squeak] Новый сайт Squeakland
:: [Squeak] Squeak для iPhone
:: [Squeak] SqueakDBX
:: [Squeak] Monticello 2
:: [GST] GNU Smalltalk 3.0.4 release
:: MagLev - Gemstone for Ruby
:: [Squeak] JSqueak, Potato
:: [Squeak] WxSqueak 0.5

Архив
Предыдущие новости / Декабрь 2004 / Январь 2005 / Февраль 2005 / Март 2005 / Апрель 2005 / Май 2005 / Июнь 2005 / Июль 2005 / Август 2005 / Сентябрь 2005 / Октябрь 2005 / Ноябрь 2005 / Декабрь 2005 / Январь 2006 / Февраль 2006 / Март 2006 / Апрель 2006 / Май 2006 / Июнь 2006 / Июль 2006 / Сентябрь 2006 / Октябрь 2006 / Ноябрь 2006 / Декабрь 2006 / Январь 2007 / Февраль 2007 / Март 2007 / Апрель 2007 / Май 2007 / Июнь 2007 / Август 2007 / Сентябрь 2007 / Ноябрь 2007 / Январь 2008 / Март 2008 / Май 2008 / Июнь 2008 / Июль 2008 / Август 2008 / Сентябрь 2008

Atom Feed
Smalltalk по-русски


Powered by Blogger