This forum is now read-only. Please use our new forums! Go to forums
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
end
double(2) do |n|
n*=2
end
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)
n*=2
end
double(2)
Can anyone explain why do we need to use yield?
Answer 51c75f68631fe903b4001e5d
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: 3.next
equals 4
, 99.next
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 = counter.next
end
end
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|
"[#{100*n}]:"
end
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.
Answer 51caff9352f8633982007a5c
this explanation also helped em alot understand the yield thingy. thanks a lot @Alex
1 comments
Glad I could help
Popular free courses
- Free Course
Learn SQL
In this SQL course, you'll learn how to manage large datasets and analyze real data using the standard data management language.Beginner friendly,4 LessonsLanguage Fluency - Free Course
Learn JavaScript
Learn how to use JavaScript — a powerful and flexible programming language for adding website interactivity.Beginner friendly,11 LessonsLanguage Fluency - Free Course
Learn HTML
Start at the beginning by learning HTML basics — an important foundation for building and editing web pages.Beginner friendly,6 LessonsLanguage Fluency
29 comments
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
It’s simply the fourth line in the function I defined above… Just replace the fragment
puts "#{counter}. #{item}"
with the fragmentputs "#{yield counter} #{item}"
inside the definition of the print_list function.thank you :)
see my answer below
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.
Holy shit that was a great explanation. I wish I could mail you a medal or at least a cuddle or something.
Thank you! This is great :)
Great explanation! Thanks a lot!
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.
Oooohh… this this is what it does. THANKS!
Thanks Alex!! Great Explanation!
Thank you Danny for raising the question. Was lost as well. Alex thank you for spending time explaining, appreciate it! XD
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!
Thank you!!
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!!
Very good explanation. Thanks I understand it now.
THANK YOU.
Godsend
Useful, nice to have a concrete example of why we might do something, instead of just how.
Yeah I agree with Toby. Thank you both.
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}>”}’
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
Thanks for such a helpful explanation!
Well done. Have you ever considered going into computer science for teaching?
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.
to retain value of first.counter value is incremented…. ‘first’ value remains the same
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!