RB Ruby

Ruby: Blocks & Iterators

What you will learn

Blocks are Ruby's most distinctive feature — chunks of code you pass to methods. They power iterators, callbacks, and custom control structures.

Block syntax: do..end vs { }

# Multi-line (preferred for longer blocks)
[1, 2, 3].each do |n|
  puts n * 2
end

# Single-line (preferred for short blocks)
[1, 2, 3].each { |n| puts n * 2 }

The |n| declares the block parameter(s). Each element is passed into the block.

Common iterators

Ruby's collection methods accept blocks and are the backbone of most Ruby code:

numbers = [1, 2, 3, 4, 5]

# each — iterate (most basic)
numbers.each { |n| puts n }

# map / collect — transform each element
doubled = numbers.map { |n| n * 2 }  # [2, 4, 6, 8, 10]

# select / filter — keep elements that match
evens = numbers.select { |n| n.even? }  # [2, 4]

# reject — keep elements that don't match
odds = numbers.reject { |n| n.even? }  # [1, 3, 5]

# reduce / inject — accumulate
sum = numbers.reduce(0) { |acc, n| acc + n }  # 15

Yield — calling a block from your own method

def repeat(times)
  times.times { yield }  # yield calls the block
end

repeat(3) { puts "Hello!" }
# Hello!
# Hello!
# Hello!

Block with explicit parameter (&block)

def with_logging(&block)
  puts "Before"
  result = block.call
  puts "After"
  result
end

with_logging { 2 + 2 }  # prints Before, After, returns 4

Common mistakes

  • Forgetting that do..end and { } have different precedence — do..end binds to the outer call, { } to the last argument. Use { } for inline, do..end for multi-line.
  • Confusing map (returns new array) with each (returns original array)
  • Using return inside a block — it returns from the enclosing method, not just the block. Use next to exit the block early instead.

Quick check below!