Диапазон (Range) представляет интервал значений — (1..10) для чисел, ('a'..'z') для букв и т. д. Диапазоны — это объекты с полезными методами, используемые для итерации, срезов, проверки принадлежности и сопоставления в case. Это лаконичная и выразительная возможность Ruby.
Создание диапазонов (.. vs ...)
(1..5) # INCLUSIVE — 1, 2, 3, 4, 5 (includes the end)
(1...5) # EXCLUSIVE — 1, 2, 3, 4 (excludes the end)
('a'..'e') # 'a', 'b', 'c', 'd', 'e' — works on letters too
Ключевое различие: .. включает конец, ... исключает его (третья точка "отодвигает конец"). Это важный момент для запоминания.
Итерация и преобразование
(1..5).each { |n| puts n } # iterate — 1 to 5
(1..5).to_a # [1, 2, 3, 4, 5] — convert to an array
(1..10).map { |n| n * 2 } # ranges support Enumerable methods
(1..100).sum # 5050
(1..10).select(&:even?) # [2, 4, 6, 8, 10]
Диапазоны включают Enumerable, поэтому они поддерживают each, map, select и т. д. — а to_a материализует их в массив.
Проверка принадлежности (эффективная)
(1..100).include?(50) # true
(1..100).cover?(50) # true — faster (doesn't iterate, just checks endpoints)
age = 25
(18..65).include?(age) # check if a value falls in a range
include?/cover? эффективно проверяют принадлежность (особенно cover?, которая просто проверяет конечные точки без итерации).
Диапазоны в case-выражениях и срезах
# case/when with ranges — clean range-based branching
grade = case score
when 90..100 then "A"
when 80..89 then "B"
when 0..79 then "F"
end
# array/string slicing with ranges
[10, 20, 30, 40, 50][1..3] # [20, 30, 40] — slice by range
"hello world"[0..4] # "hello" — substring by range
# endless/beginless ranges (Ruby 2.6+)
arr[2..] # from index 2 to the end
(1..) # 1 to infinity (with lazy evaluation)
Почему это важно
Диапазоны — это полезная и выразительная возможность Ruby, используемая во многих распространённых сценариях, поэтому их понимание — ценное повседневное знание.
Они лаконично представляют интервалы (числовые, буквенные) и появляются в нескольких частых контекстах: итерация ((1..5).each — чистый способ перебирать последовательность), срезы массивов и строк (arr[1..3], str[0..4] — элегантное извлечение подпоследовательностей), проверка принадлежности (include?/cover? — проверка, попадает ли значение в интервал, где cover? эффективна тем, что просто проверяет конечные точки), и особенно сопоставление в case/when (чистое ветвление на основе диапазонов, например оценивание по диапазонам баллов — распространённый, читаемый паттерн).
Понимание важного различия .. (включительно) vs ... (исключительно) необходимо для корректного использования диапазонов (и это частая точка путаницы).
Знание того, что диапазоны включают Enumerable (поэтому они поддерживают map/select/и т. д.), как их использовать для итерации, срезов, проверки принадлежности и сопоставления в case, а также современные возможности (бесконечные/безначальные диапазоны) охватывает практические применения.
Поскольку диапазоны часто встречаются в идиоматичном Ruby (итерация, срезы, условные выражения на основе диапазонов, проверка диапазонов значений), и поскольку они — лаконичный, выразительный способ работы с интервалами, понимание диапазонов — их синтаксиса (включительный vs исключительный), методов и частых применений (итерация, срезы, проверка принадлежности, сопоставление в case) — это полезное, практически релевантное знание для написания чистого, идиоматичного Ruby, который элегантно работает с последовательностями и интервалами.
