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! 🙂