IBM объявила о том, что 30 апреля 2006 года прекращает поддержку IBM VisualAge Smalltalk.
Однако, развитие и поддержка самого VA Smalltalk на этом не заканчивается. По соглашению с IBM далнейшим развитием, поддержкой и продвижением будет заниматься Instantiations, Inc.
Instantinations обещает, что Instantiations' VisualAge Smalltalk 7.0 появится уже в 3-м квартале этого года.
Ожидаемая стоимость - $6'995 на разработчика с 1 годичной поддержкой и апгрейдами. Пользователи версий IBM VA Smalltalk имеющие поддержку смогут обновится до Instantiations' VA Smalltalk за $1'495. Пользователи не имеющие поддержки, а так же пользователи конкурирующих диалектов смогут перейти на VAST 7 за $1'995.
Ярлыки: vast
При работе с внешними, по отношению к системе, ресурсами (например, сокеты) освобождать эти ресурсы приходится вручную. Однако, даже при работе с памятью могут существовать ситуации, когда потребуется самостоятельно очищать некоторые ссылки, чтобы избежать утечек памяти. Например, рассмотрим задачи, которые требуют присоединения произвольных атрибутов к произвольным объектам без добавления переменных объекта.
Самый распространённый пример такой задачи - хранение подписчиков на события объектов. Первоначально в ST использовалась очень простая схема, когда для добавления подписчиков используется сообщение #addDependent: с аргументом - подписчиком на события. Сейчас схема усложнилась - появилась возможность подписываться не на все события подряд, а только на те, которые интересуют, но принципиально ничего не поменялось - есть объект публикующий события и объекты-подписчики обрабатывающие события. Первое, что приходит в голову - завести переменную для хранения коллекции объектов-подписчиков. С этой схемой особых проблем нет. Коллекция объектов умрёт вместе с объектом публикующим события, а значит объекты-подписчики не будут удерживаться дольше чем нужно. Именно так и устроен класс Model. Однако, в ST подписаться на некие события можно не только у модели, а у любого объекта (простейший пример - WeakArray уведомляет своих подписчиков о смерти хранимых в нём объектов). Тут можно либо попробовать заводить переменную объекта для подписчиков в каждом классе, который может публиковать события, либо разрешить проблему сразу для всей системы задействовав класс Object. Однако, заводить переменную объекта для хранения подписчиков в классе Object не только нецелесообразно, но и невозможно в текущих реализациях виртуальных машин (ВМ).
Раз нельзя завести переменную, то прийдётся идти другим путём. А именно, заведём глобальный словарь где ключом будет объект публикующий события, а связанным с ключом значением будет коллекция подписчиков. Такие словари, где ключ это некий объект, а значение это присоединённое к объекту свойство, зачастую называют реестрами. Решение это вроде бы универсальное, но реестр то глобальный.
Для борьбы с такими ситуациями и придумали слабые ссылки (weak references). Попробуем задействовать слабые ссылки для реализации нашего реестра. Что же получится, если для хранения ключей словаря использовать слабые ссылки?
Попытка использовать для слабые ссылки для хранения значений еще более нелепа.
Получается, что нужен некий симбиоз двух подходов.
Эфемероны это разновидность ассоциации, то есть пары ключ-значение, и слабой ссылки. Поведение эфемерона такое: если есть сильные ссылки и на сам эфемерон и есть ссылки на ключ, ведущие не из самого эфемерона, то значение эфемерона удерживается. Если есть сильные ссылки на эфемерон, но нет сильных ссылок на ключ, исключая ссылки, ведущие из самого эфемерона (например от "значения" на "ключ"), то эфемерон уведомляется об этом и может обработать эту ситуацию, например, просто освободить значение или выполнить его финализацию. Обратите внимание, что эфемерон уведомляется только в том случае, если на него самого есть сильные ссылки.
Эфемероны были придуманы Георгом Босвортом (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 могут существовать классы, имеющие различную природу. Тип класса задаётся при его создании параметром indexedType:. Допустимые значения параметра: #none, #objects, #bytes, #immediate, #weak и #ephemeron. По-умолчанию тип проставляется в #none, и, поскольку прикладным программистам нет нужды создавать классы прочих типов, то описание значения этих типов будет дано другим разом. Сейчас же остановимся на типе #ephemeron.
Класс, создаваемый с indexedType: выставленным в #ephemeron, должен содержать минимум одну переменную экземпляра. Допустимо, что это переменная унаследованная от какого либо родительского класса. Такой класс должен быть унаследован от класса с типом #none и подклассы должны быть только типа #ephemeron.
Самая первая переменная экземпляра по-особому обрабатывается сборщиком мусора. Именно она и считается ключем из описания выше. То есть, если на объект в первой переменной экземпляра нет ссылок, то все прочие переменные эфемерона сборщик мусора не трассирует. Это позволяет обнаружить изолированные графы объектов. То есть графы объектов, в которых корнями являются только эфемероны. После нахождения всех таких эфемеронов сборщик мусора ложит их все в очередь для финализации, а затем трассирует все поля эфемеронов, что бы объекты в эфемеронах оставались живы.
До введения эфемеронов финализация в 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:. По-умолчанию, словарь просто удаляет ссылку на "умерший" эфемерон, позволяя сборщику мусора уничтожить граф объектов с эфемероном во главе. И так, чтобы обработать уведомление о том, что на ключ эфемерона больше нет ссылок есть несколько вариантов:
Ярлыки: vw
StorePlugins добавляет возможность получать уведомление о фактах загрузки/публикации пакетов в Store или выполнять определённые действия перед загрузкой/публикацией.
Сконфигурировать плагины можно через закладку 'Store Plugins', которая появляется если выбрать пакет в RB. Обратите внимание, что использовать это расширение можно только с той версией VW, которая указана в заголовке StorePlugins. На момент написания заметки в репозитории находилась версия предназначенная для работы с VW 7.2.1.
В состав StorePlugins уже включены несколько плагинов:
StorePlugins доступен в открытом репозитории.
Ярлыки: vw
Ярлыки: dolphin
Иногда надо найти для класса все методы, вызываемые другими классами (но не самим собой). Чтобы не копаться с senders/impementors можно попробовать это сделать автоматом во время выполнения (с помощью MethodWrappers). Запускаем код и смотрим какие методы были вызваны.
Например я хочу узнать какие методы другие классы вызывают у ProductionOrder.
ProductionOrder extractInterfaceDuring: [testRunner runSuite: DomainTestSuite new].
Открывается окно со всеми методами которые другие классы вызывают у ProductionOrder во время запуска тестов
Если надо показывать также методы определенные в суперклассах, то можно сделать так:
ProductionOrder extractInterfaceUpTo: AbstractOrder during: [testRunner runSuite: DomainTestSuite new]
Пакет ExtractInterface находится в открытом репозитории. Перед загрузкой ExtractInterface загрузите пакет MethodWrapper .
Еще одно полезное применение. Например во время рефакторинга иерархии классов часто возникает вопрос насколько сильно класс связан со своими суперклассами. Можно ли его перенести в другую иерархию. Запускаем ExtractInterface и смотрим какие методы суперклассов реально используються.
В анонсе о первом ежегодном соревновании программистов на Smalltalk проводимом STIC вкралась глупая опечатка. Регистрация не начнётся 1-го мая, а уже началась 1-го марта. Так что желающие могут уже регистрироваться.
Напомню, что регистрация заканчивается 13 мая в 18 часов EST (14 мая в 2 часа по московскому времени). 1-я фаза, продолжительностью 48 часов, начнётся в понедельник 16 мая в 9 часов утра EST (17 часов по московскому времени) и закончится в среду 18 мая в 9 часов утра EST (17 часов по московскому времени). Требования будут выложены на сайте STIC с началом первой фазы.
Если у вас есть вопросы, то возможно ответы вы найдёте в FAQ
Ярлыки: conference
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 раз) быстрее систем где часть системы написана на одном "основном" языке с критическими по времени выполнения частями на С.
Компании 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>.
Как известно, в 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.
Ярлыки: vw
Компания Mission Software рассматривает возможность сделать продукт Smalltalk/JVM open source.
Ответы на часто задаваемые вопросы по Smalltalk/JVM можно прочитать по этой ссылке.
Ambrai Smalltalk 1.0.6 Beta3 доступна для скачивания. Ambrai Smalltalk - это диалект работающий исключительно под Mac OS X. О нововведениях можно прочитать в пресс-релизе.
Так же доступен новый учебник по разработке на Ambrai Smalltalk под Cocoa.