Lazy Enumerators
Каждый раз, когда используются такие методы, как map, collect, select и тд - создаётся перечислитель. Благодаря перечислителям методы можно объединять в цепочки, например:
[1, 2, 3].map { .... }.select { .... }
Вызов методов each или select возвращает перечислитель, как показано ниже:
[1, 2, 3].each
=> #<Enumerator: ...>
[1, 2, 3].select
=> #<Enumerator: ...>
К примеру, нужно получить 10 профилей пользователей Twitter, у которых в биографии профиля есть @rails. Предположим, есть 1000 идентификаторов пользователей Twitter. Можно использовать следующий подход для получения 10 пользователей:
# Array of twitter user id's
twitter_user_ids = [...]
twitter_user_ids.map { |user_id| TwitterClient.user(user_id) }
.select { |data| data[:description].includes?("@rails") }
.first(10)
Происходит обработка всех 1000 пользователей, даже если у первых 10 пользователей в биографии был @rails.
Ленивый перечислитель позволяет получить пользователей по одному, не перебирая всех 1000 пользователей одновременно. Цикл завершается, когда получено 10 пользователей, соответствующих требуемому условию.
# Array of twitter user id's
twitter_user_ids = [...]
twitter_user_ids.lazy
.map { |user_id| TwitterClient.user(user_id) }
.select { |data| data[:description].includes?("@rails") }
.first(10)