Ruby: Итераторы

times() — простой метод, но слишком ограниченный. Что, например, делать, если нужно обходить какой-то конкретный диапазон чисел в прямом и обратном порядке? Для этого в Ruby есть методы upto() и downto():

5.upto(7) do |i|
  puts i
end
# => 5
# => 6
# => 7

Этот метод «поднимается» от цифры, на которой был вызван, до переданного числа. Исходное число и конечное включаются в обход. Вот как, например, посчитать сумму этих чисел:

result = 0
5.upto(7) do |i|
  result += i
end
puts result # => 18

Так как блок по своей сути — функция, то на него распространяются правила области видимости функций. Все, что определено внутри блока, недоступно снаружи, но блок может «замкнуть» внутри себя внешние переменные, как в примере выше. Переменные замыкаются по ссылке — это значит, что изменение переменной внутри меняет её и снаружи.

Обратите внимание на вызов метода upto() и передачу блока. Блок передается внутрь метода, но происходит это вне вызывающих скобок. Пример выше можно переписать так:

5.upto 7 do |i|
...

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

Задание

Напишите функцию average(), считающую среднее арифметическое для всех чисел в диапазоне. Функция должна возвращать Float:

average(5, 8) # (5 + 6 + 7 + 8) / 4; 26 / 4; 6.5
average(2, 4) # (2 + 3 + 4) / 3; 9 / 3; 3.0

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются https://github.com/hexlet-basics
Если вы столкнулись с трудностями и не знаете, что делать, задайте вопрос в нашем большом и дружном сообществе