Чтение онлайн

ЖАНРЫ

Программирование на языке Ruby
Шрифт:

days = month_days(2,2000) # 29 (February 2000)

days = month_days(2,2100) # 28 (February 2000)

7.24. Разбиение месяца на недели

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

nil
.

def calendar(month,year)

 days = month_days(month,year)

 t = Time.mktime(year,month,1)

 first = t.wday

 list = *1..days

 weeks = [[]]

 week1 = 7 - first

 week1.times { weeks[0] << list.shift }

 nweeks = list.size/7 + 1

 nweeks.times do |i|

weeks[i+1] ||= []

7.times do

break if list.empty?

weeks[i+1] << list.shift

end

 end

 pad_first = 7-weeks[0].size

 pad_first.times { weeks[0].unshift(nil) }

 pad_last = 7-weeks[0].size

 pad_last.times { weeks[-1].unshift(nil) }

 weeks

end

arr = calendar(12,2008) # [[nil, 1, 2, 3, 4, 5, 6],

 # [7, 8, 9, 10, 11, 12, 13],

 # [14, 15, 16, 17, 18, 19, 20],

 # [21, 22, 23, 24, 25, 26, 27],

 # [28, 29, 30, 31, nil, nil, nil]]

Чтобы

было понятнее, распечатаем этот массив массивов:

def print_calendar(month,year)

 weeks = calendar(month,year)

 weeks.each do |wk|

wk.each do |d|

item = d.nil? ? " "*4 : " %2d " % d

print item

end

puts

 end

 puts

end

# Выводится:

# 1 2 3 4 5 6

# 7 8 9 10 11 12 13

# 14 15 16 17 18 19 20

# 21 22 23 24 25 26 27

# 28 29 30 31

7.25. Заключение

В этой главе мы рассмотрели класс

Time
, который является оберткой для функций из стандартной библиотеки языка С. Были показаны его возможности и ограничения.

Мы также узнали, зачем существуют классы

Date
и
DateTime
и какую функциональность они предоставляют. Мы научились выполнять преобразования между этими классами и добавили несколько собственных полезных методов.

На этом обсуждение даты и времени завершается. Переходим к массивам, хэшам и другим перечисляемым структурам

в Ruby.

Глава 8. Массивы, хэши и другие перечисляемые структуры

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

Если не удается соединить детали, на то должна быть причина.

Ни в коем случае не пользуйтесь молотком.

Руководство по техническому обслуживанию компании IBM (1925)

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

Исторически самой первой и широко распространившейся составной структурой данных был массив. Давным-давно, еще в языке ФОРТРАН, массивы назывались индексированными переменными; сегодня они несколько видоизменились, но основная идея во всех языках одна и та же.

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

Наконец, мы рассмотрим сам модуль

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

8.1. Массивы

В Ruby массивы индексируются целыми числами; индексация начинается с нуля, как в языке С. На этом, впрочем, сходство и заканчивается.

Массивы в Ruby динамические. Можно (хотя это и не обязательно) задать размер массива при создании. Но после создания он может расти без вмешательства со стороны программиста.

Массивы в Ruby неоднородны, то есть в них могут храниться данные разных типов. На самом деле в массиве хранятся только ссылки на объекты, а не объекты как таковые. Исключение составляют только непосредственные значения, например объекта класса

Fixnum
.

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

Наконец, класс

Array
в Ruby предоставляет немало полезных функций для работы с массивами: доступ, поиск, конкатенирование и т.п. В этом разделе мы изучим встроенную функциональность и расширим ее.

8.1.1. Создание и инициализация массива

Для создания массива применяется специальный метод класса

[]
; перечисленные внутри скобок данные помещаются во вновь созданный массив. Ниже показаны три способа вызвать этот метод. (Массивы
а
,
b
и
с
инициализируются одинаково.)

a = Array.[] (1,2,3,4)

b = Array[1,2,3,4]

с = [1,2,3,4]

Имеется также метод класса

new
, который принимает 0,1 или 2 параметра. Первый параметр задает начальный размер массива (число элементов в нем). Второй определяет начальное значение каждого элемента:

Поделиться с друзьями: