Хэл Фултон - Программирование на языке Ruby
- Название:Программирование на языке Ruby
- Автор:
- Жанр:
- Издательство:ДМК Пресс
- Год:2007
- Город:Москва
- ISBN:5-94074-357-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Хэл Фултон - Программирование на языке Ruby краткое содержание
Ruby — относительно новый объектно-ориентированный язык, разработанный Юкихиро Мацумото в 1995 году и позаимствовавший некоторые особенности у языков LISP, Smalltalk, Perl, CLU и других. Язык активно развивается и применяется в самых разных областях: от системного администрирования до разработки сложных динамических сайтов.
Книга является полноценным руководством по Ruby — ее можно использовать и как учебник, и как справочник, и как сборник ответов на вопросы типа «как сделать то или иное в Ruby». В ней приведено свыше 400 примеров, разбитых по различным аспектам программирования, и к которым автор дает обстоятельные комментарии.
Издание предназначено для программистов самого широкого круга и самой разной квалификации, желающих научиться качественно и профессионально работать на Ruby.
Программирование на языке Ruby - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
t0 = Time.local(0,15,3,20,11,1979,2,324,false,"GMT-8:00")
t1 = Time.gm(*Time.now.to_a)
Однако, глядя на первый пример, не думайте, что вы сможете изменить вычисляемые параметры, например день недели (в данном случае 2 означает вторник). Такое действие противоречило бы принципам организации календаря, поэтому на созданном объекте Time
оно никак не отражается. 20 ноября 1979 года был вторник, и никакой код не сможет этого изменить.
И наконец, отметим, что есть много способов задать время некорректно, например указав тринадцатый месяц или 35-й день месяца. При любой подобной попытке возникнет исключение ArgumentError
.
7.3. Определение дня недели
Есть несколько способов определить день недели. Во-первых, метод экземпляра to_a
возвращает массив, содержащий всю информацию о моменте времени. Можно обратиться к его седьмому элементу; это число от 0 до 6, причем 0 соответствует воскресенью, а 6 — субботе.
time = Time.now
day = time.to_a[6] # 2 (вторник)
Еще лучше воспользоваться методом экземпляра wday
:
day = time.wday # 2 (вторник)
Но и тот, и другой способ не очень удобны. Иногда нужно получить день недели в виде числа, но чаще нас интересует его название в виде строки. Для этого можно обратиться к методу strftime
. Его название знакомо программистам на С. Он распознает около двадцати спецификаторов, позволяя по-разному форматировать дату и время (см. раздел 7.21).
day = time.strftime("%а") # "Tue"
Можно получить и полное название:
long = time.strftime("%А") # "Tuesday"
7.4. Определение даты Пасхи
Дату этого праздника всегда было сложно вычислить, так как она привязана к лунному календарю. Солнечный год не делится нацело на лунные месяцы, поэтому даты, основанные на таком исчислении времени, будут из года в год меняться.
Представленный ниже алгоритм хорошо известен с давних времен. Мы видели его реализацию на языках BASIC, Pascal и С. А теперь перевели и на Ruby:
def easter(year)
с = year/100
n = year - 19*(year/19)
k = (c-17)/25
i = с - c/4 - (c-k)/3 + 19*n + 15
i = i - 30*(i/30)
i = i - (i/28)* (1 -(i/28)*(29/(i + 1))*((21-n)/11))
j = year + year/4 + i + 2 - с + c/4
j = j - 7*(j/7)
l = i - j
month = 3 + (1+40)/44
day = l + 28 — 31*(month/4)
[month, day]
end
date = easter 2001 # Найти месяц и день для 2001 года,
date = [2001] + date # Добавить в начало год.
t = Time.local *date # Передать параметры Time.local.
puts t # Sun Apr 15 01:00:00 GMT-8:00 2001
Кто-то, прочитав этот раздел о Пасхе, непременно спросит: «Церковная или астрономическая?» Честно говоря, не знаю. Если вам удастся выяснить, сообщите всем нам.
Я бы с удовольствием объяснил вам этот алгоритм, только вот сам его не понимаю… Что-то надо принимать на веру, а в данном случае это особенно уместно!
7.5. Вычисление n-ого дня недели в месяце
Иногда, зная год и месяц, хочется вычислить дату, скажем, третьего понедельника или второго вторника в этом месяце. Такую задачу решает код в листинге 7.1.
Чтобы найти n-ое вхождение данного дня недели, мы передаем n в качестве первого параметра. Второй параметр — номер дня недели (0 — воскресенье, 1 — понедельник и т.д.). Третий и четвертый параметры — месяц и год соответственно.
def nth_wday(n, wday, month, year)
if (!n.between? 1,5) or
(!wday.between? 0,6) or
(!month.between? 1,12) raise ArgumentError
end
t = Time.local year, month, 1
first = t.wday
if first == wday
fwd = 1
elsif first < wday
fwd = wday - first + 1
elsif first > wday
fwd = (wday+7) - first + 1
end
target = fwd + (n-1)*7
begin
t2 = Time.local year, month, target
rescue ArgumentError
return nil
end
if t2.mday == target
t2
else
nil
end
end
Странный код в конце текста метода призван скорректировать давнюю традицию, принятую в функциях работы с датами. Если вы думаете, что попытка создать объект для представления 31 ноября приведет к ошибке, то разочарую вас. Почти все системы молчаливо преобразуют эту дату в 1 декабря. Если вы давным-давно программируете в UNIX, то, наверное, полагаете, что так и должно быть. Другие сочтут это ошибкой.
Не станем спорить о том, что должна делать системная библиотека и должен ли Ruby изменить это поведение. Но мы не хотим, чтобы наша процедура продолжала эту традицию. Если вы ищете, к примеру, пятую пятницу в ноябре 2000 года, то она вернет nil
(а не 1 декабря 2000 года).
7.6. Преобразование из секунд в более крупные единицы
Иногда нужно преобразовать заданное число секунд в дни, часы, минуты и секунды. Это можно сделать следующим образом:
def sec2dhms(seсs)
time = seсs.round # Отбрасываем микросекунды.
sec = time % 60 # Извлекаем секунды.
time /= 60 # Отбрасываем секунды.
mins = time % 60 # Извлекаем минуты.
time /= 60 # Отбрасываем минуты.
hrs = time % 24 # Извлекаем часы.
time /= 24 # Отбрасываем часы.
days = time # Дни (последний остаток).
[days, hrs, mins, sec] # Возвращаем массив [d,h,m,s].
end
t = sec2dhms(1000000) # Миллион секунд равно...
puts "#{t[0]} days," # 11 дней,
puts "#{t[1]} hours," # 13 часов,
puts "#{t[2]} minutes," # 46 минут
puts " and #{t[3]} seconds." # и 40 секунд.
Можно было пойти и дальше. Но неделю вряд ли назовешь полезной единицей, месяц не слишком точно определен, а год не всегда содержит одно и то же число дней.
Ниже приведена также обратная функция:
def dhms2sec(days,hrs=0,min=0,sec=0)
days*86400 + hrs*3600 + min*60 + sec
end
7.7. Вычисление промежутка времени, прошедшего от точки отсчета
По разным причинам может понадобиться перейти от внутреннего (традиционного) представления времени к стандартному. В системе время хранится как число секунд, прошедших с точки отсчета.
Метод класса Time.at
создает новый объект Time
, зная, сколько секунд прошло с точки отсчета:
epoch = Time.at(0) # Найти точку отсчета (1 января 1970 GMT)
newmil = Time.at(978307200) # Счастливого миллениума! (1 января 2001)
Обратная функция — это метод экземпляра to_i
, который преобразует дату в целое число.
now = Time.now # 16 Nov 2000 17:24:28
sec = now.to_i # 974424268
Если нужны микросекунды, и система поддерживает такую точность, то можно воспользоваться методом to_f
для преобразования в число с плавающей точкой.
7.8. Високосные секунды
Вот снова день исчез, как ветра легкий стон,
Из нашей жизни, друг, навеки выпал он.
Но я, покуда жив, тревожиться не стану
О дне, что отошел, и дне, что не рожден. [10] Пер. О. Румер. — Прим. ред.
Хотите иметь дело с «високосными» секундами? Мой совет: не делайте этого.
Читать дальшеИнтервал:
Закладка: