Как блок используется в итераторе?

Есть три способа передать управление в блок из метода-итератора:


  1. Управляющая структура yield

  2. метод call к Proc объекту, в который трансформировался блок, и который был передан в метод в качестве параметра

  3. вызов Proc.new, и затем метода call


yield вызывает блок и опционально передает в него один или несколько аргументов.

  def myIterator
    yield 1,2
  end
  myIterator { |a,b| puts a, b }

Результат:

  1
  2

Если в определении метода присутствует блочный аргумент (последний формальный параметр, которому предшествует амперсанд - &), этому аргументу будет присвоен блок, превращенный в Proc объект.

  def myIterator(&b)
    b.call(2,3)
  end
  myIterator { |a,b| puts a, b }

Proc.new (или синонимичные proc или lambda), будучи используемы в определении итератора, используют блок, переданный методу как аргумент, и генерируют из него Proc объект.

  def myIterator
    Proc.new.call(3,4)
    proc.call(4,5)
    lambda.call(5,6)
  end
  myIterator { |a,b| puts a, b }

Возможно, это довольно неожиданно, но Proc.new и его синонимы не расходуют блок - каждый вызов Proc.new генерирует новый Proc объект из одного и того же блока.

Внутри метода можно узнать, передан ли ему блок, используя метод block_given?.

Вход для пользователей