ФЭНДОМ


13.0

Реализация основного протокола НабораПравить

Протокол классов в ирархии Набора был описан в главах 9 и 10. В этой главе представлена полная реализация класса Набор и реализация основного протокола создания экземпляров, доступа, проверок, добавления, удаления и перебора для каждого подкласса Набора. Эти реализации широко используют каркасные сообщения класса Набор которые уточняются в этих подклассах. Сообщения Набора реализованы в очень общем виде или как сам ответственность подкласса. Методы реализуются как сам ответственность подкласса если метод зависит от представления экземпляра. Каждый класс должен переопределить такие сообщения чтобы выполнить все "ответственности подкласса". Подклассы могут переопределять и другие сообщения, из соображений эффективности, на новый метод который использует преимущества представления. Подклассы могут реализовывать некоторые методы как сам не должен реализовывать что означает что сообщение не должно посылаться экземплярам класса. Например, Набор последовательность не может отвечать на сообщение удалить:если нету:; поэтому метод реализован как сам не должен реализовывать.

Класс НаборПравить

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

имя класса Набор
суперкласс Объект
методы класса
создание экземпляра
с: объект
   сам новый добавить: объект; себя.

с: первый объект с: второй объект
   сам новый добавить: первый объект; добавить: второй объект; себя.


с: первый объект с: второй объект с: третий объект
   сам новый
      добавить: первый объект;
      добавить: второй объект;
      добавить: третий объект;
      себя.


с: первый объект с: второй объект с: третий объект с: четвёртый объект
   сам новый
      добавить: первый объект;
      добавить: второй объект;
      добавить: третий объект;
      добавить: четвёртый объект;
      себя.

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

добавить: объект

удалить: объект если нету: блок

делать: блок

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

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

добавление
добавить: новый объект
   сам ответственность подкласса.

добавить все: набор
   набор делать: [ :каждый | сам добавить: каждый. ].
   набор.

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

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

удаление
удалить: старый объект если нету: блок исключение
   сам ответственность подкласса.

удалить: старый объект
   сам
      удалить: старый объект
      если нету: [ сам ошибка не найден: старый объект. ].


удалить все: набор
   набор делать: [ :каждый | сам удалить: каждый. ].
   набор.

собственные
ошибка не найден: объект
   сам ошибка: 'Object is not in the collection.'.

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

Протокол Набора проверки Все сообщения протокола проверок состояния набора могут быть реализованы в Наборе.

проверки
пустой
   сам размер = 0.

содержит: объект
   сам любой удовлетворяет: [ :каждый | каждый = объект. ].


вхождений: объект
   | счёт |
   счёт0.
   сам делать: [ :каждый | объект = каждый истина: [ счётсчёт + 1. ]. ].
   счёт.

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

доступ
размер
   | счёт |
   счёт0.
   сам делать: [ :каждый | счётсчёт + 1. ].
   счёт.

Этот подход вычисления размера набора малоэффективен поэтому, как мы увидим, этот метод переопределён в большинстве подклассов.

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

перебор
делать: блок
   сам ответственность подкласса.

собрать: блок
   | новый набор |
   новый наборсам разновидность новый.
   сам делать: [ :каждый | новый набор добавить: (блок значение: каждый). ].
   новый набор.


выявить: блок
   сам выявить: блок если ни одного: [ сам ошибка не найден: блок. ].


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


ввести: это значение в: бинарный блок
   | следующее значение |
   следующее значениеэто значение.
   сам
      делать: [
         :каждый |
         следующее значениебинарный блок значение: следующее значение значение: каждый. ].
   следующее значение.


отбросить: блок
   сам выбрать: [ :элемент | (блок значение: элемент) == ложь. ].


собрать: блок
   | новый набор |
   новый наборсам разновидность новый.
   сам делать: [ :каждый | новый набор добавить: (блок значение: каждый). ].
   новый набор.

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

собственные
разновидность
   ↑ сам класс.

Поэтому выражение

сам разновидность новый

означает "создать новый экземпляр того же класса что и получатель." Для некоторых наборов, может быть не подходящим создавать "подобный" экземпляр в этом случае; новый набор который надо создать может быть экземпляром другого класса. Такие наборы переопределяют сообщение разновидность. В частности, Интервал отвечает что его разновидность это Ряд (т.к. невозможно изменять экземпляры Интервала); разновидность Набора отображения это разновидность отображаемого набора (т.к. Набор отображение работает как объект доступа к этому набору).

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

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

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

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

преобразование
как мешок
   Мешок со всеми: сам.

как упорядоченный набор
   сам как: Упорядоченный набор.


как множество
   Множество со всеми: сам.


как сортированный набор
   сам как: Сортированный набор.


как сортированный набор: блок сортировки
   | сортированный набор |
   сортированный наборСортированный набор новый: сам размер.
   сортированный набор сортирующий блок: блок сортировки.
   сортированный набор добавить все: сам.
   сортированный набор.

Протокол Набора печать Реализации сообщений печатать в: и поместить в: из Объекта переопределены в Наборе. Наборы печатаются в виде

имя класса (элемент элемент элемент)

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

((имя класса новый))

или

((имя класса новый) добавить: элемент; себя)

или

((имя класса новый) добавить: элемент; добавить: элемент; себя)

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

Общие методы для печати и помещения:

печать
печатать в: поток
   сам печатать имя в: поток.
   сам печатать элементы в: поток.

поместить в: поток
   | ещё не надо |
   поток пом следующими все: '(('.
   поток пом следующими все: сам класс имя.
   поток пом следующими все: ' new)'.
   ещё не надоистина.
   сам
      делать: [
         :каждый |
         ещё не надо
            истина: [ ещё не надоложь. ]
            ложь: [ поток пом следующим: $;. ].
         поток пом следующими все: ' add: '.
         поток поместить: каждый. ].
   ещё не надо ложь: [ поток пом следующими все: '; yourself'. ].
   поток пом следующим: $).

Эти методы используют экземпляры вида Потока которые являются объектами доступа к Цепи. Метод печатать в: устанавливает предел длинны создаваемой строки; длинные наборы могут напечататься как:

имя класса (элемент элемент ...и т.д. ...)

Формат печати изменён в некоторых подклассах. Ряды не печатают своё имя класса; Интервалы печатаются с использованием краткой записи при помощи сообщений до: и до:через: к Числу. Символ печатает знаки (без # в литеральной форме Символа); Цепь печатает свои знаки заключёнными в одинарные кавычки.

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

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

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

Класс МешокПравить

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

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

имя класса Мешок
суперкласс Набор
имена переменных экземпляра содержимое
методы класса
создание экземпляра
новый
   сам новый: 4.

новый: количество элементов
   супер новый
      присвоить содержимое: (сам класс содержимого новый: количество элементов).

методы экземпляра
доступ
от: номер
   сам ошибка не ключевой.

от: номер пом: объект
   сам ошибка не ключевой.


размер
   | счёт |
   счёт0.
   содержимое делать: [ :каждый | счётсчёт + каждый. ].
   счёт.

проверки
содержит: объект
   содержимое содержит ключ: объект.

вхождений: объект
   (сам содержит: объект) истина: [ содержимое от: объект. ].
   0.

собственные
присвоить содержимое: словарь
   содержимоесловарь.
(в Наборе)
ошибка не ключевой
   сам
      ошибка: ('Instances of {1} do not respond to keyed accessing messages.'
         переведённый
            формат: { сам класс имя. }).

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

добавление
добавить: новый объект
   сам добавить: новый объект с вхождениями: 1.

добавить: новый объект с вхождениями: целое
   содержимое
      от: новый объект
      пом: (содержимое от: новый объект если нету: [ 0. ]) + целое.
   новый объект.

удаление
удалить: старый объект если нету: блок исключение
   | количество |
   количествосодержимое от: старый объект если нету: [ блок исключение значение. ].
   количество = 1
      истина: [ содержимое удалить ключ: старый объект. ]
      ложь: [ содержимое от: старый объект пом: количество - 1. ].
   старый объект.

Перебор элементов Мешка означает выбор каждого элемента Словаря и выполнение блока для каждого ключа этого элемента (т.к. в действительности элемент Мешка' ' это ключ Словаря). Блок выполняется много раз, один раз для каждого вхождения элемента, как указано значением связанным с ключём.

перебор
делать: блок
   содержимое
      ассоциации делать: [ :ассоц | ассоц значение раз повторить: [ блок значение: ассоц ключ. ]. ].

Класс МножествоПравить

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

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

имя класса Множество
суперкласс Набор
имена переменных экземпляра счёт ряд
методы класса
создание экземпляра
новый
   сам основной новый инициализировать: 5.

новый: количество элементов
   супер основной новый инициализировать: (сам размер для: количество элементов).

методы экземпляра
доступ
размер
   счёт.

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

проверки
содержит: объект
   (ряд от: (сам найти элемент или пусто: объект)) ~~ пусто.

вхождений: объект
   (сам содержит: объект) истина: [ 1. ] ложь: [ 0. ].

добавление
добавить: новый объект
   | номер |
   новый объект
      пусто: [ сам ошибка: 'Sets cannot meaningfully contain nil as an element'. ].
   номерсам найти элемент или пусто: новый объект.
   (ряд от: номер) пусто: [ сам от нового номера: номер пом: новый объект. ].
   новый объект.
удаление
удалить: старый объект если нету: блок
   | номер |
   номерсам найти элемент или пусто: старый объект.
   (ряд от: номер) пусто: [ блок значение. ].
   ряд от: номер пом: пусто.
   счётсчёт - 1.
   сам устранить конфликт в: номер.
   старый объект.
перебор
делать: блок
   | каждый |
   счёт = 0 истина: [ сам. ].
   1
      до: ряд размер
      делать: [ :номер | (каждыйряд от: номер) не пусто: [ блок значение: каждый. ]. ].

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

Класс СловарьПравить

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

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

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

имя класса Словарь
суперкласс Множество
методы экземпляра
доступ
от: ключ
   сам от: ключ если нету: [ сам ошибка ключ не найден. ].

от: ключ пом: объект
   | номер ассоц |
   номерсам найти элемент или пусто: ключ.
   ассоцряд от: номер.
   ассоц
      пусто: [
         сам
            от нового номера: номер
            пом: (Ассоциация ключ: ключ значение: объект). ]
      не пусто: [ ассоц значение: объект. ].
   объект.


от: ключ если нету: блок
   | ассоц |
   ассоцряд от: (сам найти элемент или пусто: ключ).
   ассоц пусто: [ блок значение. ].
   ассоц значение.

проверки
содержит: объект
   сам делать: [ :каждый | объект = каждый истина: [ истина. ]. ].
   ложь.
добавление
добавить: ассоциация
   | номер элемент |
   номерсам найти элемент или пусто: ассоциация ключ.
   элементряд от: номер.
   элемент
      пусто: [ сам от нового номера: номер пом: ассоциация. ]
      не пусто: [ элемент значение: ассоциация значение. ].
   ассоциация.
удаление
удалить: объект если нету: блок исключение
   сам не должен реализовывать.
перебор
делать: блок
   супер делать: [ :ассоц | блок значение: ассоц значение. ].
собственные
ошибка ключ не найден
   сам ошибка: 'key not found'.

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

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

перебор
собрать: блок
   | новый набор |
   новый наборУпорядоченный набор новый: сам размер.
   сам делать: [ :каждый | новый набор добавить: (блок значение: каждый). ].
   новый набор.

выбрать: блок
   | новый набор |
   новый наборсам разновидность новый.
   сам
      ассоциации делать: [
         :каждый |
         (блок значение: каждый значение)
            истина: [ новый набор добавить: каждый. ]. ].
   новый набор.

Тождественный словарь переопределяет от:, от:пом: и добавить: чтобы сделать проверку ключей на идентичность вместо проверки на равенство.

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

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

имя класса Набор последовательность
суперкласс Набор
методы экземпляра
удаление
удалить: старый объект если нету: блок исключение
   сам не должен реализовывать.
перебор
делать: блок
   1 до: сам размер делать: [ :номер | блок значение: (сам от: номер). ].

собрать: блок
   | новый набор |
   новый наборсам разновидность новый: сам размер.
   1
      до: сам размер
      делать: [ :номер | новый набор от: номер пом: (блок значение: (сам от: номер)). ].
   новый набор.


выбрать: блок
   | поток |
   потокПоток записи на: (сам разновидность новый: сам размер).
   1
      до: сам размер
      делать: [
         :номер |
         (блок значение: (сам от: номер))
            истина: [ поток пом следующим: (сам от: номер). ]. ].
   поток содержимое.

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

Класс Связанный списокПравить

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

имя класса Связанный список
суперкласс Набор последовательность
имена переменных экземпляра первая связь последняя связь
методы экземпляра
доступ
от: номер
   | н |
   н0.
   сам делать: [ :связь | (нн + 1) = номер истина: [ связь. ]. ].
   сам ошибка границы номера: номер.
добавление
добавить: связь
   сам добавить последним: связь.

добавить последним: связь
   сам пустой
      истина: [ первая связьсвязь. ]
      ложь: [ последняя связь следующая связь: связь. ].
   последняя связьсвязь.
   связь.

удаление
удалить: связь если нету: блок
   | врем связь |
   связь == первая связь
      истина: [
         первая связьсвязь следующая связь.
         связь == последняя связь истина: [ последняя связьпусто. ]. ]
      ложь: [
         врем связьпервая связь.
         [
            врем связь пусто: [ блок значение. ].
            врем связь следующая связь == связь. ]
               пока ложь: [ врем связьврем связь следующая связь. ].
         врем связь следующая связь: связь следующая связь.
         связь == последняя связь истина: [ последняя связьврем связь. ]. ].
   связь следующая связь: пусто.
   связь.
перебор
делать: блок
   | связь |
   связьпервая связь.
   [ связь == пусто. ]
      пока ложь: [ блок значение: связь. связьсвязь следующая связь. ].

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

Класс ИнтервалПравить

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

имя класса Интервал
суперкласс Набор последовательность
имена переменных экземпляра начало конец шаг
методы класса
создание экземпляра
от: начальное целое до: конечное целое
   сам новый присвоить от: начальное целое до: конечное целое через: 1.

от: начальное целое до: конечное целое через: целое шаг
   сам новый присвоить от: начальное целое до: конечное целое через: целое шаг.

методы экземпляра
доступ
размер
   шаг < 0
      истина: [ начало < конец истина: [ 0. ]. конец - начало // шаг + 1. ]
      ложь: [ конец < начало истина: [ 0. ]. конец - начало // шаг + 1. ].

от: целое
   (целое >= 1 и: [ целое <= сам размер. ])
      истина: [ начало + (шаг * (целое - 1)). ].
   сам ошибка границы номера: целое.


от: целое пом: объект
   сам ошибка: 'you can not store into an interval'.

добавление
добавить: новый объект
   сам не должен реализовывать.
удаление
удалить: новый объект
   сам ошибка: 'elements cannot be removed from an Interval'.
перебор
делать: блок
   | значение |
   значениеначало.
   шаг < 0
      истина: [
         [ конец <= значение. ]
            пока истина: [ блок значение: значение. значениезначение + шаг. ].
         пусто. ]
      ложь: [
         [ конец >= значение. ]
            пока истина: [ блок значение: значение. значениезначение + шаг. ].
         пусто. ].

собрать: блок
   | след значение результат |
   результатсам разновидность новый: сам размер.
   след значениеначало.
   1
      до: результат размер
      делать: [
          |
         результат от: н пом: (блок значение: след значение).
         след значениеслед значение + шаг. ].
   результат.

собственные
присвоить от: начальное целое до: конечное целое через: целое шаг
   началоначальное целое.
   конецконечное целое.
   шагцелое шаг.

Наборы ряды - Ряд, Ряд байтов, Цепь, Текст и СимволПравить

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

Из подклассов Набора ряда Ряд и Ряд байтов не переопределяют сообщений которые был рассмотрены в этой главе. Методы доступа для Цепи - от:, от:пом: и размер - это примитивы системы; в Тексте все сообщения доступа направляются к переменной экземпляра цепь (которая является экземпляром Цепи). Символ не допускает сообщения от:пом: и возвращает Цепь в качестве своей разновидности.

Упорядоченные наборы и Сортированные наборыПравить

Упорядоченный набор хранит порядок, непрерывную последовательность элементов. Т.к. Упорядоченный набор расширяемы, то эффективность этого набора получается за счёт выделения дополнительного пространства для последовательности. Две переменных экземпляра, первый номер и последний номер указывают на первый и последний элемент в последовательности.

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

имя класса Упорядоченный набор
суперкласс Набор последовательность
имена переменных экземпляра ряд первый номер последний номер
методы класса
создание экземпляра
новый
   сам новый: 10.

новый: целое
   супер основной новый присвоить набор: (Ряд новый: целое).

методы экземпляра
доступ
размер
   последний номер - первый номер + 1.

от: целое
   (целое < 1 или: [ целое + первый номер - 1 > последний номер. ])
      истина: [ сам ошибка нету такого элемента. ]
      ложь: [ ряд от: целое + первый номер - 1. ].


от: целое пом: объект
   | номер |
   номерцелое как целое.
   (номер < 1 или: [ номер + первый номер - 1 > последний номер. ])
      истина: [ сам ошибка нету такого элемента. ]
      ложь: [ ряд от: номер + первый номер - 1 пом: объект. ].

добавление
добавить: новый объект
   сам добавить последним: новый объект.

добавить последним: новый объект
   последний номер = ряд размер истина: [ сам создать пространство в конце. ].
   последний номерпоследний номер + 1.
   ряд от: последний номер пом: новый объект.
   новый объект.

удаление
удалить: старый объект если нету: блок исключение
   первый номер
      до: последний номер
      делать: [
         :номер |
         старый объект = (ряд от: номер)
            истина: [ сам удалить номер: номер. старый объект. ]. ].
   блок исключение значение.
собственные
ошибка нету такого элемента
   сам ошибка: 'attempt to index non-existent element in an ordered collection'.

Каждое из сообщений перебора делать, собрать: и выбрать: переопределено - делать: чтобы предоставить большую производительность чем метод предоставленный Набором последовательностью.

перебор
делать: блок
   первый номер
      до: последний номер
      делать: [ :номер | блок значение: (ряд от: номер). ].

собрать: блок
   | новый набор |
   новый наборсам разновидность новый: сам размер.
   первый номер
      до: последний номер
      делать: [
         :номер |
         новый набор добавить последним: (блок значение: (ряд от: номер)). ].
   новый набор.


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

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

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

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

Экземпляры Набора отображения имеют две переменные экземпляра - область и карта. Значение домена это любой Словарь или Набор последовательность; доступ к его элементам осуществляется через карту. Сообщение добавить: недопустимо. Оба сообщения от: и от:пом: переопределены в Наборе последовательности чтобы поддерживать не прямой доступ через карту к элементам области.

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

новый
   сам
      ошибка: 'MappedCollections must be created using the collection:map: message'.

методы экземпляра
доступ
от: номер
   область от: (карта от: номер).

от: номер пом: объект
   область от: (карта от: номер) пом: объект.


размер
   карта размер.

добавление
добавить: новый объект
   сам не должен реализовывать.
перебор
делать: блок
   карта
      делать: [ :значение карты | блок значение: (область от: значение карты). ].

собрать: блок
   | поток |
   потокПоток записи на: (сам разновидность новый: сам размер).
   сам
      делать: [
         :значение области |
         поток пом следующим: (блок значение: значение области). ].
   поток содержимое.


выбрать: блок
   | поток |
   потокПоток записи на: (сам разновидность новый: сам размер).
   сам
      делать: [
         :значение области |
         (блок значение: значение области)
            истина: [ поток пом следующим: значение области. ]. ].
   поток содержимое.

собственные
присвоить набор: набор карту: словарь
   областьнабор.
   картасловарь.

разновидность
   область разновидность.

Обнаружено использование расширения AdBlock.


Викия — это свободный ресурс, который существует и развивается за счёт рекламы. Для блокирующих рекламу пользователей мы предоставляем модифицированную версию сайта.

Викия не будет доступна для последующих модификаций. Если вы желаете продолжать работать со страницей, то, пожалуйста, отключите расширение для блокировки рекламы.

Также на ФЭНДОМЕ

Случайная вики