Understanding Yield & Yield_Self in Ruby (Complete Guide)

What does the word “yield” mean in Ruby? And what does it do exactly?

Well…

Yield is a keyword (meaning it’s a core part of the language) & it’s used inside methods for calling a block.

In other words, yield is pausing our method & transfering control to the block so that it can do its thing & then come back with a return value.

Here’s what you need to know:

  • Calling a block runs the code inside that block (like calling a method).
  • Yield can pass any number of arguments to the block.
  • The block’s return value becomes the return value for yield.

You have to understand blocks for this to make sense.

You can think of blocks as methods without names that can be passed as (implicit) arguments to other methods.

Here’s an example:

def make_salad
  yield "lettuce"
  yield "carrots"
  yield "olive oil"
end

make_salad { |ingredient| puts "Adding #{ingredient} to salad!" 
}

Here we define a make_salad method, notice that it doesn’t take any arguments in this example, but it could just like any other methods.

Then we call this method & we send in a block (all the stuff between curly brackets {}, including those).

The result of the code above is this output:

Adding lettuce to salad!
Adding carrots to salad!
Adding olive oil to salad!

This is the essence of what yield does, the mechanics are similar to calling any other method, but it allows you to pass a function as an argument & not just data.

Now:

Let’s explore what happens if you don’t have a block to call.

Yield Without a Block (no block given error)

If you call yield without having a block, then you get an error.

Example:

def write_code
  yield
end

write_code

# LocalJumpError: no block given (yield)

This error is crystal-clear, “no block given” means that the method call write_code is not providing a block, which is required to use yield.

How can you prevent this error?

Like this:

def write_code
  yield if block_given?
end

The block_given? method checks if a block is available & this allows you to only yield if that’s true.

Why Use Yield?

Using yield enables blocks.

We use blocks to pass in bits of code as part of a method call.

That’s helpful when:

  • You want to write a generic logging function, that logs how long a bit of code takes to run
  • You want to run some code when the method is done (like “callbacks” in Javascript)
  • You want “lazy code”, code that only runs when needed & that can be customized by the user (for an example of this, read about the Hash#fetch method)

Nice!

Yield_Self – What’s The Difference?

You may find this new yield_self method & think it’s related to yield.

Well, it isn’t.

Even yield(self) is different, because self refers to the current object.

Where yield_self, which was was added in Ruby 2.5, refers to the object we’re calling the method on.

A good use for this method?

Use it whenever you want to chain methods & do something with the object you’re calling yield_self on.

While returning the results, instead of the original object.

Example:

n_squared = ->(n) { n ** 2 }

2
.yield_self(&n_squared)
.yield_self(&n_squared)

# 16

In Ruby 2.6, there is an alias for yield_self, the then method.

But don’t confuse it with your regular yield.

Ok?

Yield in Rails

I should also give a quick mention to the use of yield in Rails & templating engines.

You’ll find yield inside layouts.

Rails replaces it with the contents of the view you’re rendering.

No yield equals empty layout!

That’s how the layout & your views are combined together.

Summary

You have learned about the yield keyword in Ruby! Exactly what it is, how it works & why it matters.

Now give it a try in your Ruby code.

Thanks for reading! 🙂