Ruby: containers, blocks, iterators

Posted on Апрель 29, 2008. Filed under: ruby |

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

Контейнеры

Прежде чем начать определять класс, нужно понять как хранить список песен внутри объекта СписокПесен. У нас есть три очевидных выбора. Можно использовать класс Array, класс Hash или создать свою структуру реализующую список. Мы люди ленивые, поэтому рассмотрим массивы (arrays) и хеши (hashes) и выберем один из них для нашего класса.

Массивы

Класс Array содержит коллекцию ссылок на объекты. Каждая такая ссылка имеет в массиве позицию, определяемую неотрицательным индексом.
Вы можете создавать массивы используя литералы или явно создавая объект Array. Литерал массива это просто список объектов разделенный запятой и заключенный в квадратные скобки.

a = [ 3.141592, "pie", 99 ]
>> a.class → Array
>> a.length → 3
>> a[0] → 3.141592
>> a[1] → "pie"
>> a[2] → 99
>> a[3] → nil
b = Array.new
>> b.class → Array
>> b.length → 0
>> b[0] = "second"
>> b[1] = "array"
>> b → ["second", "array"]

Массивы индексируются с использованием оператора [ ]. Как и большинство операторов Ruby, на самом деле это метод класса (метод экземпляра класса Array) и поэтому может быть перегружен в подклассах. Как показывает пример, индексы массивов начинаются с нуля. Примените взятие неотрицательного индекса к массиву и он вернет объект на этой позиции или объект nil, если там ничего нет. Если возьмете индекс отрицательный, то он вернет индекс с конца.
Но это еще не все: можно брать индекс, используя пару чисел, [start, count]. Это вернет новый массив состоящий из ссылок на count объектов начиная с позиции start.

a = [ 1, 3, 5, 7, 9 ]
>> a[1, 3] → [3, 5, 7]
>> a[3, 1] → [7]
>> a[-3, 2] → [5, 7]

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

 a = [ 1, 3, 5, 7, 9 ]
>>  a[1..3] → [3, 5, 7]
>>  a[1...3] → [3, 5]
>>  a[3..3] → [7]
>>  a[-3..-1] → [5, 7, 9]

У оператора [] есть соответствующий ему оператор []=. Он позволяет устанавливать элементы в массиве. Если он используется с одним числом, то элемент на этой позиции замещается тем, что расположено в правой части выражения присваивания. Любые промежутки, возникнувшие в результате этой операции замещаются nil.

>> a = [ 1, 3, 5, 7, 9 ] → [ 1, 3, 5, 7, 9 ]
>> a[1] = 'bat' → [ 1, "bat", 5, 7, 9 ]
>> a[-3] = "cat" → [ 1, "bat", "cat", 7, 9 ]
>> a[-3] = 'cat' → [ 1, "bat", "cat", [9, 8], 9 ]
>> a[6] = 99  → [ 1, "bat", "cat", [9, 8], 9, nil, 99 ]

Если индекс []= состоит из двух чисел (начало и конец), тогда элементы исходного массива замещаются тем, что находится справа от оператора присваивания. Если длина равна 0, правая часть вставляется в массив перед стартовой позицией, элементы не удаляются. Если правая часть сама является массивом, то его элементы используются при замене. Размер массива автоматически меняется, если количество элементов, которые выбирает индексация больше, чем количество элементов исходного массива.

>> a = [ 1, 3, 5, 7, 9 ] → [ 1, 3, 5, 7, 9 ]
>> a[2, 2] = 'cat' → [1, 3, "cat", 9]
>> a[2, 0] = 'dog' → [1, 3, "dog", "cat", 9]
>> a[1, 1] = [9, 8, 7] → [1, 9, 8, 7, "dog", "cat", 9]
>> a[0..3] = [] → ["dog", "cat", 9]
>> a[5..6] = 99, 98 → ["dog", "cat", 9, nil, nil, 99, 98]

У массивов есть много других полезных методов. Используя их, можно обращаться с массивами как со стеками, множествами, очередями и обратными очередями.
Все это — вольный перевод Dave Thomas — Programming ruby 2nd edition (The Pragmatic Programmers’ Guide)

Реклама

Make a Comment

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

Liked it here?
Why not try sites on the blogroll...

%d такие блоггеры, как: