Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
def to_proc
proc {|obj, *args| obj.send(self, *args) }
end
Кстати, этот код заимствован из проекта Гэвина Синклера (Gavin Sinclair) «Расширения Ruby». Имея такой метод, мы можем следующим образом переписать первоначальный код:
list = words.map(&:capitalize)
Стоит потратить немного времени и разобраться, как это работает. Метод
map
&
proc
to_proc
map
self
proc
self
to_proc
6.2. Диапазоны
Понятие диапазона интуитивно понятно, но и у него имеются некоторые неочевидные особенности и способы применения. Одним из самых простых является числовой диапазон:
digits = 0..9
scalel = 0..10
scale2 = 0...10
Оператор
..
...
digits
scale2
Но диапазоны могут состоять не только из целых чисел — более того, не только из чисел. Началом и концом диапазона в Ruby может быть любой объект. Однако, как мы вскоре увидим, не все диапазоны осмыслены или полезны.
Основные операции над диапазоном — обход, преобразование в массив, а также выяснение, попадает ли некоторый объект в данный диапазон. Рассмотрим разнообразные варианты этих и других операций.
6.2.1. Открытые и замкнутые диапазоны
Диапазон называется замкнутым, если включает конечную точку, и открытым — в противном случае:
r1 = 3..6 # Замкнутый.
r2 = 3...6 # Открытый.
a1 = r1.to_a # [3,4,5,6]
а2 = r2.to_a # [3,4,5]
Нельзя сконструировать диапазон, который не включал бы начальную точку. Можно считать это ограничением языка.
6.2.2. Нахождение границ диапазона
Методы
first
last
begin
end
r1 = 3..6
r2 = 3...6
r1a, r1b = r1. first, r1.last # 3,6
r1c, r1d = r1.begin, r1.end # 3,6
r2a, r2b = r1.begin, r1.end # 3,6
Метод
exclude_end?
r1.exclude_end? # false
r2.exclude_end? # true
6.2.3. Обход диапазона
Обычно диапазон можно обойти. Для этого класс, которому принадлежат границы диапазона, должен предоставлять осмысленный метод
succ
(3..6).each {|x| puts x } # Печатаются четыре строки
# (скобки обязательны).
Пока все хорошо. И тем не менее будьте очень осторожны при работе со строковыми диапазонами! В классе
String
succ
succ
r1 = "7".."9"
r2 = "7".."10"
r1.each {|x| puts x } # Печатаются три строки.
r2.each {|x| puts x } # Ничего не печатается!
Предыдущие примеры похожи, но ведут себя по-разному. Отчасти причина в том, что границы второго диапазона — строки разной длины. Мы ожидаем, что в диапазон входят строки
"7"
"8"
"9"
"10"
При обходе диапазона
r2
"7"
"7"
"10"
А что сказать по поводу диапазонов чисел с плавающей точкой? Такой диапазон можно сконструировать и, конечно, проверить, попадает ли в него конкретное число. Это полезно. Но обойти такой диапазон нельзя, так как метод
succ
fr = 2.0..2.2
fr.each {|x| puts x } # Ошибка!
Почему для чисел с плавающей точкой нет метода
succ
6.2.4. Проверка принадлежности диапазону
Зачем нужен диапазон, если нельзя проверить, принадлежит ли ему конкретный объект? Эта задача легко решается с помощью метода
include?
r1 = 23456..34567