Что такое итераторы и как они работают?ruby-7

Что такое итераторы?

Итераторы в Ruby — это методы, которые позволяют последовательно обрабатывать элементы коллекции (массивы, хэши, диапазоны) без явного использования циклов. В отличие от традиционных циклов, итераторы:

  • Инкапсулируют логику перебора
  • Принимают блоки кода
  • Обрабатывают коллекции в функциональном стиле

Основные встроенные итераторы

1. each - базовый итератор

[1, 2, 3].each { |x| puts x * 2 }
# Вывод: 2, 4, 6

2. map/collect - трансформация

squares = [1, 2, 3].map { |x| x**2 }
# => [1, 4, 9]

3. select/reject - фильтрация

evens = [1, 2, 3, 4].select(&:even?)
# => [2, 4]

4. reduce/inject - агрегация

sum = [1, 2, 3].reduce(0) { |acc, n| acc + n }
# => 6

Как работают итераторы?

1. Механизм yield

Итераторы используют yield для передачи управления в блок:

def my_each(array)
  i = 0
  while i < array.length
    yield(array[i]) # Передаем элемент в блок
    i += 1
  end
  array
end

my_each([1,2,3]) { |x| puts x }

2. Проверка наличия блока

def my_iterator
  if block_given?
    yield 42
  else
    puts "Блок не передан"
  end
end

3. Итераторы с Enumerator

Без блока возвращается Enumerator:

enum = [1,2,3].each
enum.next # => 1

Создание собственного итератора

Пример итератора для диапазона чисел:

class NumericRange
  def initialize(start, stop)
    @start, @stop = start, stop
  end

  def each
    current = @start
    while current <= @stop
      yield current
      current += 1
    end
  end
end

range = NumericRange.new(1, 3)
range.each { |n| puts n }

Ленивые итераторы

(1..Float::INFINITY).lazy
  .select(&:odd?)
  .take(5)
  .to_a
# => [1, 3, 5, 7, 9]

Резюмируем

  1. Итераторы — методы для обработки коллекций с блоками
  2. Основные виды:
    • each для перебора
    • map для трансформации
    • select/reject для фильтрации
    • reduce для агрегации
  3. Работают через:
    • yield для передачи управления в блок
    • block_given? для проверки
    • Возвращают Enumerator без блока
  4. Можно создавать:
    • Кастомные итераторы
    • Ленивые цепочки обработки
  5. Преимущества:
    • Читаемость кода
    • Избегание side effects
    • Функциональный стиль