Smalltalk по-русски
VasyaVasya (обсуждение | вклад)
Нет описания правки
Eugenius (обсуждение | вклад)
м Смолток. Язык и его реализация/Вторая часть/10. Ирархия классов наборов» переименована в «[[Смолток. Язык и его реализация/Вторая часть/10. )
(нет различий)

Версия от 11:22, 3 января 2008

10.0

Ирархия классов наборов

10.diagramma

На рисунке 10.1 представлена схема для нахождения различных классов наборов системы. Следуя выбору на рисунке удобно определять какой вид набора использовать в реализации.

10

Рисунок 10.1

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

Один из неупорядоченных наборов с внешними ключами это Словарь. Его ключами обычно являются экземпляры Цепи или Ключа поиска; для проверки ключей на совпадение используется равенство (=). Словарь имеет подкласс, Тождественный словарь чьи внешние ключи обычно являются Символами. У него проверка ключей на совпадение это эквивалентность (==). Элементы Мешка или Множества не упорядочены и не доступны через внешние ключи. Доблирование позволяется в Мешке, но не во Множестве.

Все упорядоченные наборы это виды Набора последовательности. Элементы всех Наборов последовательностей доступны через ключ целое число. Четыре подкласса Набора последовательности предоставляют различные способы создания порядка элементов. Дополнительное различие между классами Набора последовательности это возможность хранить элементы которые являются экземплярами любого класса или экземплярами некоторого вида объектов.

Порядок элементов определяется внешним образом для Набора последовательности, Связанного списка и Набора ряда. Для Набора последовательности и Связанного списка последовательность действий программы по добавлению и удалению элементов определяет порядок элементов. Элементом Набора последовательности может быть любой объект, в то время как элементом Связанного списка может быть только вид Связи. Различные Наборы ряды системы включают Ряд, Цепь и Ряд байтов. Элементами Ряда или Ряда серий может быть объект любого вида, элементами Цепи или Текста должны быть Знаки, и элементами Ряда байтов должны быть Малые целые между 0 и 255.

Порядок элементов определяется самими элементами для Интервалов и Сортированных наборов. Для Интервалов, порядок это арифметическая прогрессия которая задаётся при создании экземпляра. Для Сортированного набора, порядок определяется по условию сортировки заданному блоком известным набору. Элементами Интервала должны быть Числа; элементам Сортированного набора могут быть любые виды объектов.

В дополнение к уже упомянутым классам наборов существует и Набор отображение, это набор который предоставляет косвенный доступ к набору чьи элементы доступны через внешний ключ. Это отображение одного множество внешних ключей на другое задаётся во время создания Набор отображение.

Дальше в этой главе рассматривается каждый из подклассов наборов, описывается добавление к протоколу сообщений и приводятся простые примеры.

Класс Мешок

Мешок это простейший вид набора. Он представляет собой набор чьи элементы не упорядочены и не имеют внешних ключей. Это подкласс Набора. Т.к. его экземпляры не имеют внешних ключей, то он не отвечает на сообщения от: и от:пом:. Сообщение размер возвращает общее количество элементов в наборе.

Мешок это просто группа элементов который ведёт себя соответственно протоколу для всех наборов. Общее описание наборов не ограничивает количество повторений элемента в наборе. Класс Мешок подчёркивает эту общность определяя дополнительное сообщение для добавления элементов.

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

Рассмотрим класс пример Продукт который представляет бакалейный товар и его цену. Новый продукт может быть создать при помощи сообщения с: имя за: цена, и цена экземпляра доступна при помощи сообщения цена. Заполнение корзины можно представить так:

   пакетМешок новый.
   пакет добавить: (Продукт с: #steak за: 5.80).
   пакет добавить: (Продукт с: #potatoes за: 0.50) с вхождениями: 6.
   пакет добавить: (Продукт с: #carrots за: 0.10) с вхождениями: 4.
   пакет добавить: (Продукт с: #milk за: 2.20).

Затем можно определить плату за покупки при помощи предложений

   количество0.
   пакет
      делать: [ :каждый продукт | количествоколичество + каждый продукт цена. ].

или

   пакет
      ввести: 0
      в: [ :количество :каждый продукт | количество + каждый продукт цена. ].

получится 11.40 $. Заметьте что сообщения добавить:, делать: и ввести:в: наследуются Мешком от своего суперкласса, Набора.

Мешок является неупорядоченным, т.е. не смотря на то что поддерживаются сообщения перебора не известно в каком порядке будут перебираться элементы.

Класс Множество

Класс Множество представляет набор чьи элементы неупорядочены и не имеют внешних ключей. Его экземпляры не отвечают на сообщение от: и от:пом:. Множество подобно Мешку за исключением того что его элементы не могут дублироваться. Сообщение добавления добавляет элемент только если он ещё не в наборе. Класс Множество это подкласс класса Набор.

Классы Словарь и Тождественный словарь

Класс Словарь представляет набор связей между ключами и значениями. Элементы словаря это экземпляры класса Ассоциация, простейшей структуры данный для хранения пары ключ-значение.

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

Сообщения унаследованные от класса Объект - от: и от:пом: - применяются к ключам Словаря. Принцип сообщений от: и от:пом: расширяется для ассоциаций и значений при помощи дополнительный сообщений ассоциация от: и ключ от значения:. Для предоставления дополнительного контроля при поиске элементы в Словаре есть сообщение от:если нету:, используя его программист может задать действие в случае если элементы с ключём равным первому аргументу не найден. Наследуемое сообщение от: сообщает об ошибке если ключ не найден.

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

В качестве примера использования Словаря рассмотрим словарь Символов антонимов.

   антонимыСловарь новый.
   антонимы от: #горячий пом: #холодный.
   антонимы от: #толкать пом: #тянуть.
   антонимы от: #стой пом: #иди.
   антонимы от: #приходи пом: #иди.

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

   антонимыСловарь новый.
   антонимы добавить: (Ассоциация ключ: #перед значение: #зад).
   антонимы добавить: (Ассоциация ключ: #верх значение: #низ).

Словарь антонимы сейчас содержит:

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

Воспользовавшись протоколом проверки унаследованным от класса Набор проверить значения словаря. Заметьте что включает: проверяет присутствие значения, а не ключа.

предложение результат
антонимы размер. 6
антонимы содержит: #холодный. истина
антонимы содержит: #горячий. ложь
антонимы вхождений: #иди. 2
антонимы от: #стой пом: #старт. старт

Четвёртый пример показывает что не смотря на то что ключ может встречаться тольк один раз значение может быть связано с любым количеством ключей. Последний пример пересвязывает ключ #стой с новым значением #старт. Классом Словарь предоставляются дополнительные сообщения для проверки ассоциаций и ключей.

Протокол экземпляров Словаря
проверка словаря
содержит ассоциацию: ассоциация Отвечает содержит ли получатель элемент (ассоциацию между ключём и значением) который равен аргументу, ассоциация.
содержит ключ: ключ Отвечает есть ли у получателя ключ равный аргументу, ключ.

Поэтому можно проверить:

предложение результат
антонимы содержит ассоциацию: (Ассоциация ключ: #приходи значение: #иди). истина
антонимы содержит ключ: #горячий. истина

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

Протокол экземпляров Словаря
удаление из словаря
удалить ключ: ключ Удаляет ключ (и его ассоциацию) из получателя. Если в получателе нету ключа, сообщается об ошибке. Иначе возвращается значение связанное с ключём.
удалить ключ: ключ если нету: блок Удаляет ключ (и его ассоциацию) из получателя. Если в получателе нету ключа, то возвращается результат выполнения блока. Иначе возвращается значение именуемое ключём.

Например:

предложение результат
антонимы удалить ключ: #горячий. Ассоциация чей ключ это #горячий и чьё значение это #холодный. Ассоциация удаляется из антонимов.
антонимы удалить ключ: #холодный если нету: [ антонимы от: #холодный пом: #горячий. ].

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

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

Протокол экземпляров Словаря
перебор словаря
ассоциации делать: блок Выполняет блок для каждой ассоциации получателя между ключём и значением.
ключи делать: блок Выполняет блок для каждого ключа получателя.

Таким образом есть три пути для перебора элементов в Словаре. Допустим новые слова это Множество слов которые дети ещё не выучили. Любое слово находящиеся в антонимах используется детьми и может быть удалено из новых слов. Выполние двух следующих предложений удаляет эти слова (первое удаляет значение, второе ключ).

   антонимы делать: [ :слово | новые слова удалить: слово если нету: [ ]. ].
   антонимы
      ключи делать: [ :слово | новые слова удалить: слово если нету: [ ]. ].

Заметьте что если слова из антонимов нет в новых словах, то ничего не происходит (нет сообщения об ошибке). Также можно использовать одно предложение перебирающие Ассоциации.

   антонимы
      ассоциации делать: [
         :каждая |
         новые слова удалить: каждая ключ если нету: [ ].
         новые слова удалить: каждая значение если нету: [ ]. ].

Сообщения доступа ключи и значения могут быть использованы для получения наборов слов из словаря антонимы. Предполагая что все предыдущие примеры выполнены, получим:

антонимы ключи

возвратит Набор чьими элементами будут:

толкать приходи перед стой холодный

и

антонимы значения

возвратит Мешок чьи элементы это:

тяни иди зад старт горячий

Класс Набор последовательность

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

Протокол экземпляров Набора последовательности
доступ
от всех: набор пом: объект Связывает каждый элемент аргумента, набор (целое или другой внешний ключ), со вторым аргументом, объект.
от всех пом: объект Помещает аргумент, объект, в качестве каждого элемента получателя.
первый Возвращает первый элемент получателя. Сообщает об ошибке если у получателя нету элементов.
последний Возвращает последний элемент получателя. Сообщает об ошибке если у получателя нету элементов.
номер для: элемент Возвращает первый номер аргумента, элемент, в получателе. Если получатель не содержит элемента, то возвращается 0.
номер для: элемент если нету: блок исключение Возвращает первый номер аргумента, элемент, в получателе. Если получатель не содержит элемента, то возвращается результат выполнения аргумента блок исключение.
номер поднабора: поднабор начиная с: номер Если элементы аргумента, поднабор, встречаются в данном порядке в получателе, то возвращается номер первого элемента первого вхождения. Если совпадений нету, то возвращается 0.
номер поднабора: поднабор начиная с: номер если нету: блок исключение Возвращет номер первого элемента получателя такого что этот элемент равен первому элементу аргумента, поднабор, и последующие элементы равны оставшимся элементам поднабора. Поиск в получателе начинается с элемента с номером равным аргументу, номер. Если совпадений не находится, то возвращается результат выполнения аргумента блок исключение.
заменить от: начало до: конец на: набор замена Связывает каждый номер между началом и концом с элементами аргумента, набор замена. Возвращает получателя. Количество элементов в наборе замене должно совпадать со значением конец - начало + 1.
заменить от: начало до: конец на: набор замена начиная с: начало замены Связывает каждый номер между началом и концом с элементами аргумента, набор замена, начиная с элемента набора замены чей номер это начало замены. Возвращает получателя. Проверка границ не производится, за исключением если получатель такой же как набор замена но начало замены не 1, тогда произойдёт сообщается об ошибке выхода за границы.

Примеры использования методов доступа, используется экземляры Цепи.

предложение результат
'аааааааааа' размер. 10
'аааааааааа' от всех: (2 до: 10 через: 2) пом: . 'абабабабаб'
'аааааааааа' от всех пом: . 'бббббббббб'
'Эта цепь' первый.
'Эта цепь' последний.
'АБВГДЕЁЖЗИКЛМНОП' номер для: . 6
'АБВГДЕЁЖЗИКЛМНОП' номер для: если нету: [ 0. ]. 13
'АБВГДЕЁЖЗИКЛМНОП' номер для: если нету: [ 0. ]. 0
'The cow jumped' номер поднабора: 'cow' начиная с: 1. 5
'The cow jumped' заменить от: 5 до: 7 на: 'dog'. 'The dog jumped'
'The cow jumped' заменить от: 5 до: 7 на: 'the spoon ran' начиная с: 5. 'The spo jumped'

Любой из этих примеров должен работать подобным образом с любым экземпляром подкласса Набора последовательности, например, с Рядом. Для Ряда, #(#The #brown #jug), замена brown на black производится предложением.

#( #The #brown #jug ) заменить с: 2 до: 2 на: #( #black )

Заметьте что последний аргумент должен быть Рядом. Так же заметьте что сообщение замена не изменяет размер исходного набора (получателя), хотя оно изменяет набор. Может понадобиться сохранить исходный набор создав его копию. Протокол копировани Набора последовательности поддерживает копирование последовательности элементов набора, копирование всего набора с заменой его части, копирование всего набора с удалением элементов или копирование всего набора с добавлением одного или нескольких элементов.

Протокол экземпляров Набора последовательности
копирование
, набор последовательность Это операция соединения. Возвращает копию получателя с добавленными элементами аргумента, набор последовательность.
копия от: начало до: конец Возвращает копию подмножества получателя, начиная с элемента с номером начало до элемента с номером конец.
копия с заменой всех: старый поднабор на: новый поднабор Возвращает копию получателя в которой все вхождения старого поднабора заменены на новый поднабор.
копия с заменой от: начало до: конец на: набор замена Возвращает копию получателя удовлетворяющую следующим условиям: если конец меньше чем начало, то это вставка; конец должен быть точно равен началу - 1. начало = 1 означает что это вставка перед первым элементом, начало = размер + 1 означает добавление после последнего элемента. Иначе это замена; начало и конец должны лежат в пределах получателя.
копия с: новый элемент Возвращает копию получателя которая больше на 1 элемент, новый элемент, добавленный в конец.
копия без: старый элемент Возвращает копию получателя в которой нет вхождений старого элемента.

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

строкаЦепь новый: 0.

Тогда

предложение результат
   строкастрока копия с заменой от: 1 до: 0 на: 'this is the first line tril'. 'this is the first line tril'
   строкастрока копия с заменой всех: 'tril' на: 'trial'. 'this is the first line trial'
   строкастрока
      копия с заменой от: строка размер + 1
      до: строка размер
      на: 'and so on'.
'this is the first line trialand so on'
   строка номер поднабора: 'trial' начиная с: 1. 24
   строкастрока копия с заменой от: 29 до: 28 на: ' '. 'this is the first line trial and so on'

Два последних сообщения протокола копирования, описанного выше, полезны для получения копий Ряда с или без элемента. Например:

предложение результат
#( #один #два #три ) копия с: #четыре. (один два три четыре)
#( #один #два #три ) копия без: #два. (один три)

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

Протокол экземпляров Набора последовательности
перебор
найти первый: блок Выполняет блок для каждого элемента получателя. Возвращает номер первого элемента для которого блок вернул истину.
найти последний: блок Выполняет блок для каждого элемента получателя. Возвращает номер последнего элемента для которого аргумент, блок, вернул истину.
реверсивно делать: блок Выполняет блок для каждого элемента получателя, начиная от последнего элемента и последовательно до первого элемента. Для Набора последовательности это обратный перебор по сравнению с делать:. блок это блок с одним аргументом.
с: набор последовательность делать: блок Выполняет блок для каждого элемента получателя вместе со соответствующим элементом из набора последовательности. набор последовательность должен быть того же размера что и получатель, и блок должен быть двухаргументным блоком.

Следующие предложения создают Словарь, антонимы, который был использован в предыдущих примерах.

   антонимыСловарь новый.
   #( #приходи #холодный #перед #горячий #толкать #стой )
      с: #( #иди #горячий #зад #холодный #тянуть #старт )
      делать: [ :ключ :значение | антонимы от: ключ пом: значение. ].

Сейчас Словарь имеет шесть ассоциаций в качестве элементов.

Любой Набор последовательность может быть преобразован в Ряд или MappedCollection. Сообщения делающие это: как ряд и mappedBy: aSequenceableCollection.

Подклассы Набора последовательности

Подклассы Набора последовательности это Упорядоченный набор, Связанный список, Интервал и MappedCollection. Набор ряд это подкласс представляющий набор элементов с фиксированным диапазоном целых в качестве внешних ключей. Подклассы Набора рядя это, например, Ряд и Цепь.

Класс Упорядоченный набор

Упорядоченынй набор упорядочивается при помощи последовательности в которой объекты добавляются и удаляются из него. Элементы доступны через внешние ключи являющиеся номерами. Протоколы доступа, добавления и удаления расширены для ссылания на первый и последний элементы, и на элементы предшествующие или следующие за другим элементом.

Упорядоченный набор может работать как стэк или очередь. Стэк это последовательный список для которого все добавления и удаления производятся с одной стороны списка (называемой или тыл или фронт). Стэк часто описывают выражением: последним вошёл первым вышел.

обычный словарь сообщения Упорядоченного набора
поместить новый объект добавить последним: новый объект
извлечь удалить последний
вершина последний
пустой пустой

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

обычный словарь сообщения Упорядоченного набора
добавить новый объект добавить последним: новый объект
удалить удалить первый
фронт первый
пустой пустой

Для Упорядоченного набора сообщение добавить: означает "добавить элемент в набор последним" и удалить: означает "удалить элемент равный аргументу". Протокол сообщений для Упорядоченного набора, в дополнение к унаследованному от классов Набор и Набор последовательность, включает:

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

Класс Сортированный набор

Класс Сортированный набор это подкласс Упорядоченного набора. Элементы Сортированного набора упорядочиваются функцией двух аргументов. Функция представляетя блоком называемым сортирующий блок. Добавление элемента возможно только сообщением добавить:; такие сообщения как добавить последним: которые позволяют программисту определять порядок вставления не допускаются для Сортированного набора.

Экземпляр класса Сортированный набор можно создать послав Сортированному набору сообщения сортирующий блок:. Аргументом для этого сообщения служит двухаргументный блок, например:

Сортированный набор сортирующий блок: [ | а <= б. ].

Данный блок это функция сортировки по умолчанию для случаев когда экземпляр создаётся при помощи сообщения новый. Таким образом четыре примера создания Сортированного набора это:

   Сортированный набор новый.
   Сортированный набор сортирующий блок: [ | а > б. ].
   любой набор как сортированный набор.
   любой набор как сортированный набор: [ | а > б. ].

Можно задать блок и сбросить блок используя два дополнительных сообщения к экземпляру Сортированного набора. Когда блок изменяется элементы набора, конечно же, пересортировываются. Заметьте что то же самое сообщение посылается классу (сортирующий блок:) для создания экземпляра с заданным условием сортировки, и экземпляру для изменения его условия.

Протокол класса Сортированный набор
создание экземпляра
сортирующий блок: блок Возвращает экземпляр Сортированного набор такой что его элементы будут отсортированы в соответствии с условием заданным аргументом, блок.
Протокол экземпляров Сортированного набора
доступ
сортирующий блок Возвращает блок который является условием сортировки элементов получателя.
сортирующий блок: блок Делает аргумент, блок, условием сортировки элементов получателя.

Допустим нам нужен алфавитный список имён детей из класса.

детиСортированный набор новый.

Начальное условие сортировки это блок по умолчанию [ :а :б | а <= б. ]. Элементами набора могут быть Цепи или Символы потому что, как будет сказано позднее, эти виды объектов отвечают на сообщения сравнения <, >, <= и >=.

предложение результат
дети добавить: #Joe. Joe
дети добавить: #Bill. Bill
дети добавить: #Alice. Alice
дети. Сортированный набор (Alice Bill Joe)
дети добавить: #Sam. Sam
дети сортирующий блок: [ | а < б. ]. Сортированный набор ((Sam Joe Bill Alice)
дети добавить: #Henrietta. Henrietta
дети. Сортированный набор (Sam Joe Henrietta Bill Alice)

Шестое сообщение примера изменяет порядок в котором элементы хранятся в наборе дети.

Класс Связанный список

Связанный список это другой подкласс Набора последовательности чьи элементы явно упорядочиваются порядком в котором они добавляются или удаляются из набора. Подобно Упорядоченному набору, на элементы Связанного списка можно ссылаться при помощи номеров. В отличии от Упорядоченного набора, чьими элементами могут быть любые объекты, элементы Связанного списка однородны; каждый элемент должен быть экземпляром класса Связь или его подкласса.

Связь это запись ссылки на другую Связь. Её протокол сообщений содержит три сообщения. То же самое сообщение (следующая ссылка:) используется для создания экземпляра Связи с данной ссылкой, и для изменения ссылки экземпляра.

Протокол класса Связанный список
создание экземпляра
следующая связь: связь Создаёт экземпляра Связи которая ссылается на аргумент, связь.
Протокол экземпляра Связанного списка
доступ
следующая связь Возвращает ссылку получателя.
следующая связь: связь Присваивает ссылке получателя аргумент, связь.

Т.к. класс Связь не предоставляет способа записи действительного элемента набора, то он рассматривается как абстрактный класс. Поэтому, экземпляры этого класса не создаются. Вместо этого определяются подклассы которые предоставляют механизм для запоминания одного или нескольких элементов, и создаются экземпляры подклассов.

Т.к. Связанный список это подкласс Набора последовательности, то его экземпляры могут отвечать на сообщения доступа, добавления, удаления и перебора определённые для всех наборов. Дополнение протокола для Связанного списка состоит из:

Протокол экземпляра Связанного списка
добавление
добавить первым: связь Добавляет связь в начало списка получателя. Возвращает связь.
добавить последним: связь Добавляет связь в конец списка получателя. Возвращает связь.
удаление
удалить первый Удаляет первый элемент получателя и возвращает его. Если получатель пуст, то сообщается об ошибке.
удалить последний Удаляет последний элемент получателя и возвращает его. Если получатель пуст, то сообщается об ошибке.

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

Дальше идёт пример использования Связанного списка. Связь не предоставляет информации кроме ссылки на другую связь. Поэтому, для примера, предположит что есть подкласс Связи с именем Запись. Запись добавляет возможность хранить объект. Сообщения создания экземпляра Записи это для: объект, и её сообщение доступа это элемент.

имя класса Запись
суперкласс Связь
имена переменных экземпляра элемент
методы класса
создание экземпляра
для: объект
   сам новый задать элемент: объект.
методы экземпляра
доступ
элемент
   элемент.
печать
печатать в: поток
   поток пом следующим все: 'Запись для: ' , элемент цепь для печати.
собственные
задать элемент: объект
   элементобъект.

Затем классы Связанный список и Запись можно использовать так:

предложение результат
списокСвязанный список новый. Связанный список ()
список добавить: (Запись для: 2). Запись для: 2
список добавить: (Запись для: 4). Запись для: 4
список добавить последним: (Запись для: 5). Запись для: 5
список добавить первым: (Запись для: 1). Запись для: 1
список. Связанный список (Запись для: 1 Запись для: 2 Запись для: 4 Запись для: 5)
список пустой. ложь
список размер. 4
список ввести: 0 в: [ :значение :каждый | каждый элемент + значение. ]. 12
список последний. Запсь для: 5
список первый. Запись для: 1
список удалить: (Запись для: 4). Запись для: 4
список удалить первый. Запись для: 1
список удалить последний. Запись для: 5
список первый == список последний. истина

Класс Интервал

Другой вид Набора последовательности это набор чисел представляющий математическую прогрессию. Например, набор может содержать все целые в интервале от 1 до 100; или он может содержать все чётные целые в интервале от 1 до 100. Или набор может содержать последовательность чисел в которой каждое следующее число последовательности вычисляется из предыдущего умножением его на 2. Последовательность может начинаться с 1 и заканчиваться числом которое меньше или равно 100. Это будет последовательность 1, 2, 4, 8, 16, 32, 64.

Математическая прогрессия описывается первым числом, пределом (максимум или минимум) для последнего вычисляемого числа, и методом вычисления следующего числа. Предел может быть положительной или отрицательной бесконечностью. В случае арифметической прогрессии метод вычисления это просто добавление приращения. Например, это может быть последовательность чисел в которой каждое следующее число вычисляется из предыдущего добавлением -20. Последовательность может начинаться со 100 и заканчиваться числом большим либо равным 1. Это должна быть последовательность 100, 80, 60, 40, 20.

В системе Смолток класс последовательности называемый Интервал содержит конечные арифметические прогрессии. В дополнение к сообщениям наследуемым от суперкласса Набор последовательность и Набора, класс Интервал поддерживает сообщения для доступа к значениям которые описывает экземпляр. Новые элементы не могут быть добавлены или удалены из Интервала.

Протокол класса Интервал содержит следующие сообщения для создания экземпляров.

Протокол класса Интервал
создание экземпляра
от: начальное целое до: конечное целое Возвращает экземпляр класса Интервал, начинающийся с числа начальное целое, заканчивающийся числом конечное целое и использующий для вычисления следующего элемента приращение 1.
от: начальное целое до: конечное целое через: целое шаг Возвращает экземпляр Интервала, начинающйся с числа начальное целое, заканчивающийся числом конечное целое и использующий приращение целое шаг для вычисления следующего элемента.

Интервалу могут быть посланы все сообщения понимаемые Набором последовательностью. В дополнение к этому, протокол экземпляра Интервала предоставляет сообщения для доступа к шагу арифметической прогрессии (шаг).

Класс Число предоставляет два сообщения которые являются сокращениями для создания новых Интервалов: до: конец и до: конец через: шаг. Поэтому чтобы создать Интервал целых от 1 до 10, нужно выполнить:

Интервал от: 1 до: 10.

или

1 до: 10.

Чтобы создать Интервал начинающийся со 100 и заканчивающийся 1, добавляющий -20, нужно выполнить:

Интервал от: 100 до: 1 через: -20.

или

100 до: 1 через: -20.

Это последоватеьность 100, 80, 60, 40, 20. Интервал может содержать не только Целые; чтобы создать Интервал между 10 и 40, с шагом 0.2, выполните:

Интервал от: 10 до: 40 через: 0.2.

или

10 до: 40 через: 0.2.

Это последовательность 10, 10.2, 10.4, 10.6, 10.8, 11.0, ... и т.д.

Заметьте что можно создать более общий вид прогрессии заменив численное значение шага блоком. Когда новый элемент будет вычислен, он будет послан в качестве аргумента сообщения значение: блоку.

Сообщение делать: Интервалу делает то же что обычный цикл for в языках программирования. Выражения на Алголе

for i := 10 step 6 until 100 do begin < statements > end

представляется так:

(10 до: 100 через: 6) делать: [ | предложения. ].

Числа отвечают на сообщения до:через:делать: хотя предложения можно писать и как в данном примере. Поэтому итерация может быть записана без скобок:

10 до: 100 через: 6 делать: [ | предложения. ].

Чтобы увеличить на 1 каждый шестой элемент Упорядоченного набора выполните:

   6
      до: числа размер
      через: 6
      делать: [ :номер | числа от: номер пом: (числа от: номер) + 1. ].

Созданный Интервал состоит из 6, 12, 18, ..., до номера последнего элемента чисел. Если размер набора меньше чет 6 (подразумеваемый первый номер), то ничего не происходит. Иначе элемента в позициях 6, 12, 18, и т.д., до последнего возможного элемента заменяются на новые.

Класс Набор ряд

Как было сказано раньше класс Набор ряд это подкласс Набора. Он представляет набор элементов с фиксированным диапазоном целых в качестве внешних ключей. В системе Смолток Набор ряд имеет пять подклассов: Ряд, Цепь, Текст, Ряд серий и Ряд байтов.

Ряд это набор чьи элементы это любые объекты. Он предоставляет конкретное представление для хранения набора элементов которые используют числа в качестве внешнего ключа. Несколько примеров использования Рядов уже было дано в этой главе.

Цепь это набор чьи элементы это Знаки. В этой и в предыдущих главах было дано много примеров использования Цепей. Класс Цепь предоставляет дополнительный протокол для инициализации и сравнения своих экземпляров.

Текст представляет Цепь у которой есть шрифт и выделение. В системе Смолток он используется для хранения информации нужной для создания текстовых документов. Экземпляры Текста имеют две переменные экземпляра, Цепь и экземпляр Ряда серий в котором хранится изменение шрифта и выделения.

Класс Ряд серий предоставляет эффективный по памяти способ хранения данных которые не изменяются на больших интервалах индексов. Он запоминает повторяющийся элемент один раз и связывает с каждым элементом число которое показывает число последовательных вхождений элемента. Например, допустим что Текст представляет Цепь 'He is a good boy.' которая показывается со словом "boy" выделеным жирным шрифтом, и также допустим что код для шрифта это 1 и для его жирного варианта это 2. Тогда Ряд серий для Текста который связан с 'He is a good boy.' (Цепь из 17 знаков) содержит 1 связанную с 13, 2 связанную с 3, и 1 связанную с 1. Поэтому первые 13 Знаков имеют шрифт 1, следующие 3 шрифт 2, и последний знак шрифт 1.

Ряд байтов представляет Набор ряд чьи элементы это целые между 0 и 255. Реализация Ряда байтов запоминает два байта в 16-битных словах; класс поддерживает дополнительный протокол для доступа к словам и двойным словам. Ряд байтов используется в системе Смолток для хранения времени в миллисекундах.

Класс Цепь

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

Протокол экземпляров Цепи
сравнение
< цепь Отвечает следует ли получатель перед аргументом, цепь. Сравнение производится в АСКОИ (ASCII) с игнорированием регистра.
<= цепь Отвечает следует ли получатель перед аргументом, цепь, или равен ей. Сравнение производится в АСКОИ (ASCII) с игнорированием регистра.
> цепь Отвечает следует ли получатель за аргументом, цепь. Сравнение производится в АСКОИ (ASCII) с игнорированием регистра.
>= цепь Отвечает следует ли получатель за аргументом, цепь, или равен ей. Сравнение производится в АСКОИ (ASCII) с игнорированием регистра.
сопоставить с: цепь Рассматривает получатель как образец который содержить знаки # и *. Отвечает совпадает ли аргумент, цепь, с образцом получателя. Сопоставление игнорирует различие в регистре. Когда получатель содержит знак #, цепь может содержать любой один знак. Когда получатель содержит знак *, цепь может содержать любую последовательность знаков, в том числе ни одного.
такой же как: цепь Отвечает равен ли словарно получатель аргумент, цепь. Сравнение производится в кодировке АСКОИ с игнорированием регистра.

До сих пор не было примеров использования последних двух сообщений.

предложение результат
'first string' такой же как: 'first string'. истина
'First String' такой же как: 'first string'. истина
'First String' = 'first string'. ложь
'#irst string' сопоставить с: 'first string'. истина
'* string' сопоставить с: 'any string'. истина
'*.st' сопоставить с: 'filename.st'. истина
'first string' сопоставить с: 'first *'. ложь

Цепь можно преобразовать к виду со всеми маленькими буквами или со всеми большими. Их также можно преобразовать в экземпляр класса Символ.

Протокол экземпляров Цепи
преобразование
в нижнем регистре Возвращает Цепь созданную из получателя со всеми знаками в нижнем регистре.
в верхнем регистре Возвращает Цепь созданную из получателя со всеми знаками в нижнем регистре.
как символ Возвращает уникальный Символ чьи знаки это знаки получателя.

Поэтому получаем

предложение результат
'first string' в верхнем регистре. 'FIRST STRING'
'First String' в нижнем регистре. 'first string'
'First' как символ. First

Класс Символ

Символы это ряды Знаков для которых гарантируется уникальность. Поэтому

'a string' как символ == 'a string' как символ.

возвратит истину. Символ предоставляет два сообщения для создания экземпляров в протоколе класса.

Протокол класса Символ
создание экземпляра
содержащий: цепь Возвращает уникальный Символ чьи знаки такие же как у цепи.
содержащий знак: знак Возвращает уникальный Символ из одного знака, аргумента знак.

В дополнение к этому, Символы можно создавать литерально, используя знак # как приставки к последовательности Знаков. Например, #dave это Символ из черытёх знаков. Символы печатаются без приставки.

Класс Набор отображение

Класс Набор отображение это подкласса Набора. Он представляет механизм доступа для ссылания на поднабор набора чьи элменты поименованы. Это отображение может определять перестановку или фильтр элементов набора. Основная идея состоит в том что Набор отображение ссылается на область и на карту. Область это Набор который используется для косвенного доступа через внешние ключи карты. Карта это Набор которы связывает набор внешних ключей с другим множеством внешних ключей. Это второе множество ключей должно быть внешними ключами которые можно использовать для доступа к элементам области. Поэтому область и карта должны быть экземплярами Словаря, или его подкласса или подклассом Набора последовательности.

Возьмём, например, Словарь слов Символов, синонимы, введёный ранее.

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

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

ключ значение
прекрати стой
входи приходи
обжигающий горячий
пихай толкай

Замет можно создать Набор отображение выполнив предложение:

словаНабор отображение набор: антонимы карта: синонимы.

При помощи слов можно получить доступ к антонимам. Например, значение предложения слова от: #пректари это старт (т.е. значение ключа прекрати в синонимах это стой, значение ключа стой в атонимах это старт). Можно определить какая часть антонимов доступна через слова при помощи сообщения содержимое.

слова содержимое.

Результат это Мешок содержащий символы старт, иди, холодный, тянуть.

Сообщение от:пом: это косвенный способ изменить набор область. Например:

предложение результат
слова от: #обжигающий. холодный
слова от: #прекрати. старт
слова от: #прекрати пом: #продолжай. продолжай
антонимы от: #стой. продолжай

Краткое изложение преобразования между Наборами

В разделе описывающем различные виды наборов было указано что виды наборов могут преобразовываться друг в друга. Подводя итог, любой набор можно преобразовать в Мешок, Множество, Упорядоченный набор или Сортированный набор. Все наборы за исключением Мешка и Множества могут быть преобразованы в Ряд или Набор отображение. Цепи и Символы могут преобразовываться друг в друга, но ни один набор не может быть преобразован в Интервал или Связанный список.