Today I learned
Read about some cool stuff.
Lazy enumerators in Ruby
22 sie 2025

The main differences between standard (eager) enumerators and lazy ones lie in how they process data through chains of enumerations. Standard enumerators handle this in a sequential manner, while lazy enumerators pass each value through the entire chain one by one.

def do_a(x)
  puts "Doing A with #{x}"
  x
end

def do_b(x)
  puts "Doing B with #{x}"
  x
end


result = (1..5)
  .map { do_a(it) }
  .map { do_b(it) }
  .take_while { it < 3 }
  .to_a

# Doing A with 1
# Doing A with 2
# Doing A with 3
# Doing A with 4
# Doing A with 5
# Doing B with 1
# Doing B with 2
# Doing B with 3
# Doing B with 4
# Doing B with 5

puts result.inspect # [1, 2]

# ----

result = (1..5)
  .lazy
  .map { do_a(it) }
  .map { do_b(it) }
  .take_while { it < 3 }
  .to_a

# Doing A with 1
# Doing B with 1
# Doing A with 2
# Doing B with 2
# Doing A with 3
# Doing B with 3

puts result.inspect # [1, 2]

There are three main benefits of using lazy enumerators:

  1. You can stop early. No need to process all the data if you've already gathered the required results. Methods like first and take_while are your friends here.
  2. They are CPU-efficient. By using enumerators like select, you can stop further processing of an item at any step of the chain.
  3. They are memory-efficient. They don't build intermediate arrays, so the data used in processing can be released right after handling the current item. This is especially useful when dealing with files or fetching data from URLs.
ul. Powstańców Warszawy 5
15-129 Białystok
+48 668 842 999
SKONTAKTUJ SIĘ Z NAMI