This forum is now read-only. Please use our new forums! Go to forums

0 points
Submitted by Anu
over 9 years

I don't really understand what is this yield

I got the exercise correctly and my code is as below

def double(n)
yield n


double(2) do |n|

But my question is I don’t really understand why need to do like this when there is a more easier way like the following

def double(n)



Can anyone explain why do we need to use yield?

Answer 51c75f68631fe903b4001e5d

215 votes


In the very simple example you presented, yield doesn’t make much sense indeed. But the mechanism of yielding to blocks in Ruby provides the programmer with a great flexibility. A block is simply a chunk of code, and yield allows you to “inject” that code at some place into a function. So if you want your function to work in a slightly different way, you don’t have to write a new function, instead you can reuse the one you already have, but give it a different block.

For example, consider a function that will print the members of an Array, but number them, like this: if you give it ["apple","banana"], it should print

1. apple
2. banana

Easy enough, right? There are several ways to do this, but I’ll just use each and a counter. Instead of incrementing the counter via += 1, I’d like to use the next method (you’ll see why in a moment). Here’s how the next method works: equals 4, is 100 and so on. So here’s our method (without yield):

def print_list(array, first = 1)
  counter = first
  array.each do |item|
    puts "#{counter}. #{item}"
    counter =

Now when we call print_list(["Ruby", "Python", "C"]), it’ll print

1. Ruby
2. Python
3. C

The second parameter first is optional (it defaults to 1 because of the first=1 above) and it tells our function where to start counting:

print_list(["a","b","c"], 99)

will print

99. a
100. b
101. c

Because I chose next over += 1 to increment the counter, and because Ruby is really awesome, we can use strings instead of numbers to label the list items: "A".next is "B", and so forth. Thus

print_list(["Ruby", "Python", "C"], "X")

# will print:

X. Ruby
Y. Python
Z. C

Great, right? But what if we wanted a different format for the item labels? Say, (1), (2), (3) instead of 1., 2., 3.? Our function does the formatting in this line:

puts "#{counter}. #{item}"

So instead of having two (almost identical) functions – one for 1. 2. and one for (1) (2) (and so on, one for every possible idea), we’re going to export that formatting thing into a block, and have just a yield inside the function:

# function print_list, line 4:
puts "#{yield counter} #{item}"

Now we can have a block handle the formatting:

print_list( [1,2,3], 23 ) { |n| "<#{n}>"}

# produces: 

<23> 1
<24> 2
<25> 3

Now I hope you see how this yield adds flexibility to your method. You can, for instance, have something like this:

print_list( ["alpha","beta","gamma"], 5 ) do |n|

This prints… can you guess what it prints? Try to figure it out, then go here to find out the answer and see more examples.

Submitted by Alex J
over 9 years


Anu over 9 years

Thanks a lot Alex. I got how yield works from your explanation. Though I didn’t understand some of the codes you given for the different printing formats.

I don’t understand this part:

function print_list, line 4:

puts “#{yield counter} #{item}”

I do understand what the “yield” does in there, but where did the # function print_list, line 4:” come from? Very confused

Alex J over 9 years

It’s simply the fourth line in the function I defined above… Just replace the fragment puts "#{counter}. #{item}" with the fragment puts "#{yield counter} #{item}" inside the definition of the print_list function.

Alex J about 9 years

see my answer below

Brian W about 9 years

I would just like to say that if an example “doesn’t make much sense” as you point out, it’s probably not a good idea to use it to introduce new concepts in a beginner’s tutorial.

Snarik about 9 years

Holy shit that was a great explanation. I wish I could mail you a medal or at least a cuddle or something.

Anna Baik almost 9 years

Thank you! This is great :)

alibedde over 8 years

Great explanation! Thanks a lot!

Danny Sullivan over 8 years

Thank you for this explanation. For me, a lot of these exercises lack context, it is hard to see exactly how and why you would use whatever it is you are learning. Your explanation cleared that up in the first two sentences. I wish Codecademy would start to incorporate more examples of why you would use something instead of just giving an exercise.

Oleg Joel Malinovsky over 8 years

Oooohh… this this is what it does. THANKS!

znapper over 8 years

Thanks Alex!! Great Explanation!

Kyler Chua over 8 years

Thank you Danny for raising the question. Was lost as well. Alex thank you for spending time explaining, appreciate it! XD

Anne N over 8 years

Thank you so much for explaining this! I was so confused as to how yield was applicable when other methods work just as well for this particular assignment. Much appreciated!

Alex over 8 years

Thank you!!

Mantas Jonušas over 8 years

good explanation. but why don’t do formating in the puts line: puts “<#{counter}> #{item}” and etc. and do things as simple as possible

Thank you much!!

Todd Mathews about 8 years

Very good explanation. Thanks I understand it now.

Bekah about 8 years


bumblebeezel almost 8 years


Toby almost 8 years

Useful, nice to have a concrete example of why we might do something, instead of just how.

Leah Suter almost 8 years

Yeah I agree with Toby. Thank you both.

NYJY85 almost 8 years

Thank you for the explanation! But I am wondering how does ruby know that ‘n’ refers to the second parameter and not the first in ‘print_list( [1,2,3], 23 ) { |n| “<#{n}>”}’

Ti Pro over 7 years

I think because n is a number, a symbol not is an array. Beside that, yield make you have a prametter so ruby will follow this parameter to do with block

Jenn Goble over 7 years

Thanks for such a helpful explanation!

Spencer Romberg about 7 years

Well done. Have you ever considered going into computer science for teaching?

Michael Du about 7 years

I know this post is 2 years old, but hoping you’re still around for questions: Why do we need “counter” in your example? It works perfectly fine using “first” directly within the block.

Nitya Narayan about 7 years

to retain value of first.counter value is incremented…. ‘first’ value remains the same

BlackFiresong about 7 years

Amazing! Thank you so much. I was really mystified by the whole yield thing. Thanks for taking the time to write such a detailed explanation. If you’re not a teacher by profession, you should be!

Answer 51caff9352f8633982007a5c

0 votes


this explanation also helped em alot understand the yield thingy. thanks a lot @Alex

Submitted by siaw23™
over 9 years


Alex J over 9 years

Glad I could help

Answer 53c9cd74631fe9afa9000054

0 votes


Great explanation, thanks

Submitted by Ray Rai
about 8 years