yield: running the block a method received

Free preview 2 min to read

What each, map, and select were doing all along

The last three courses used each, map and select constantly, methods that receive a block and run it. None of them showed how a method does that. The answer is yield.

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

greet { puts "Hello from the block!" }
# Before the block
# Hello from the block!
# After the block

yield, anywhere in a method's body, runs the block passed to that method, at that point. greet never names the block. yield is the whole mechanism: one keyword meaning "run the block now."

Any method you define can accept a block

This course builds on one idea: each, map and select aren't magic. They're ordinary methods that run a block this way, and any method you write can do the same.

Ruby can show you where a method lives. Method#source_location returns where a method was defined, or nil when it's implemented in C:

[].method(:each).source_location   # => nil, implemented in C
[].method(:map).source_location    # => nil, implemented in C
1.method(:times).source_location   # => ["<internal:numeric>", 255], written in Ruby

In the standard interpreter, each and map are written in C for speed. On Ruby 4.0, times is written in Ruby, and you can read it. Either way the mechanism is this lesson's: receive a block and run it with yield. Nothing about it is reserved for built-in methods.

def twice
  yield
  yield
end

twice { puts "hi" }
# hi
# hi

twice calls yield twice, so the block runs twice. That's how 3.times { ... } works: times calls yield a set number of times in a row.

Key takeaways

  • yield runs the block passed to the method, at the point where it's written.
  • A method doesn't need to name its block to use yield.
  • Calling yield several times runs the block several times, which is how times works.
  • each, map and select use this same mechanism; they aren't special language features.
Lesson 1 of 7 · free

Keep going with lesson 2

yield with arguments

Passes values into the block with yield, rebuilds the core of each, and uses the block's return value.

A free account also gives you the quizzes, your progress and notes, and the discussion.

Type to start searching...