Menu
Coddy logo textTech

The yield Keyword

Part of the Logic & Flow section of Coddy's Ruby journey — lesson 17 of 56.

Methods you define yourself can take a block, just like the built-in ones. Inside the method, the keyword yield runs the block the caller passed in.

def greet
  puts "Before block"
  yield
  puts "After block"
end

greet do
  puts "Hi from the block!"
end
# Before block
# Hi from the block!
# After block

You can pass arguments to the block by giving them to yield:

def with_each(items)
  items.each { |item| yield item }
end

with_each([10, 20, 30]) { |n| puts n }
# 10
# 20
# 30

If a method calls yield but the caller didn't pass a block, Ruby raises an error. block_given? lets you check first:

def maybe
  yield if block_given?
end

maybe                       # nothing happens
maybe { puts "called!" }    # called!
challenge icon

Challenge

Easy

Define a method named repeat that takes one argument n (an integer) and yields the values 1, 2, ..., n to its block, one at a time.

Then call your method with n = 4 and a block that prints "Got <value>" for each yielded value.

The output is:

Got 1
Got 2
Got 3
Got 4

Cheat sheet

Use yield inside a method to run the block passed by the caller:

def greet
  yield
end

greet { puts "Hi!" } # Hi!

Pass arguments to the block via yield:

def with_each(items)
  items.each { |item| yield item }
end

with_each([1, 2]) { |n| puts n }

Use block_given? to check if a block was provided before calling yield:

def maybe
  yield if block_given?
end

Try it yourself

# TODO: define `repeat` that yields 1..n to its block

# TODO: call repeat(4) with a block that prints "Got <value>"
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Logic & Flow