Ruby Yield
Yield is one of the most powerful concepts implemented in the Ruby programming language. Yield lets you branch from within a method and execute some external code, then return to the original code in the first method.
What's so special about yield in Ruby? You could get the same branch and return flow by just executing a method call in java, or a function call in C.
Heck, COBOL's PERFORM verb implements branch and return behavior. So what's up with yield?
Well, the behavior of what you branch to is set in stone with all those other techniques, but is undetermined until coded in Ruby. Yield is kind of like a place holder that says "I'm going to branch off and do something here, but I don't know what I'm going to do yet".
Maybe some examples will help make it more clear. Here is a Ruby method with some yields coded in it, then the code to invoke the method and the block of code to invoke when the yield is encountered:
def block1 puts "Start of block1..." yield yield puts "End of block1." end block1 {puts "yielding..."}
Running this code would produce the following output:
Start of block1... yielding... yielding... End of block1.
So block1 executes it's first line and prints "Start of block1...", then it executes the yields which branch to the block of code outside block1 but associated with it at run time, then comes back and prints "End of block1."
OK that's, fine but isn't that functionally the same as the following code:
def block2 puts "Start of block2..." put_it("in put_it called method...") put_it("still in put_it called method...") puts "End of block2." end def put_it(text) puts text end block2
Running this second set of code produces the following:
Start of block2... in put_it called method... still in put_it called method... End of block2.
For the most part, these are pretty much the same. However without having to redefine any methods I could immediately execute the block1 method with a different block associated with it. The yield would branch and execute this newly associated logic:
block1 {require 'time' puts Time.now.httpdate}
This produces the output:
Start of block1... Tue, 05 Jun 2007 19:20:35 GMT Tue, 05 Jun 2007 19:20:35 GMT End of block1.
The hard coded function call in block2 forever ties the branching logic to the put_it function. To get different behavior you would need to either change the function call in block2 to call a different function, or change the behavior of the function put_it. This second way is brittle because it could break code elsewhere that calls put_it. The first is cumbersome and possibly brittle.
Ruby's yield is a wonderful construct.
What about when you don't want to branch, but want the other functionality in the block1 code to be executed? Can you just run the code without the associated block?
Let's see what happens. Running block1 without an attached block for the yield to associate to:
block1
This produces the result:
Start of block1...
LocalJumpError: no block given
from
from
from :0
We get a 'no block given' error at line 3 in method 'block1'. Line 3 is our first yield in the block1 method.
What to do?
We can wrap the yield in an if statement and check for the presence of a block using the block_given? conditional. It returns true if a block was given with the method call, or false if not.
For this example I'll use a slightly more idiomatic way of checking for the presence of a block in ruby:
def block3 puts "Start of block3..." yield if block_given? puts "End of block3." end
now if we run the code with a block:
block3 { puts "yielding" }
or without:
block3
It works both times producing:
Start of block3...
yielding...
End of block3.
and
Start of block3...
End of block3.
This will make your methods less brittle and more agile.
Ruby's yield is worth getting to know. You can learn more here and here. Many of Ruby's built in methods contain yields that allow you to associate blocks with them producing added functionality at run time.
Mar 10, 2023 03:52:18 AM
I truly like you're composing style, incredible data, thankyou for posting. buy clenbuterol online
Apr 26, 2023 01:44:10 AM
It is perfect time to make some plans for the future and it is time to be happy. I've read this post and if I could I desire to suggest you some interesting things or suggestions. Perhaps you could write next articles referring to this article. I want to read more things about it! The Lord of the Rings: The Rings of Power Bronwyn Cape
Jul 10, 2023 09:41:29 PM
I see some amazingly important and kept up to length of your strength searching for in your on the site KERASSENTIALS REVIEWS
Jul 23, 2023 06:14:24 AM
It was a very good post indeed. I thoroughly enjoyed reading it in my lunch time. Will surely come and visit this blog more often. Thanks for sharing. 41215663
Jul 24, 2023 11:28:29 PM
The next time I read a blog, I hope that it doesnt disappoint me as much as this one. I mean, I know it was my choice to read, but I actually thought you have something interesting to say. All I hear is a bunch of whining about something that you could fix if you werent too busy looking for attention. GLUCOFREEZE
Aug 28, 2023 05:00:31 AM
Here at this site really the fastidious material collection so that everybody can enjoy a lot. Matt Davies
Dec 05, 2023 04:57:00 AM
I recently came across your article and have been reading along. I want to express my admiration of your writing skill and ability to make readers read from the beginning to the end. I would like to read newer posts and to share my thoughts with you. UFABETโปรโมชั่นเว็บบอล
Jan 25, 2024 10:58:06 PM
Board Model Papers 2024 Download with Suggestions for 10th Class Textbooks 2024 Pdf Download and SSLC New Syllabus Sample Question Paper 2024 and different types of model papers boardmodelpaper.com and question papers for following the website and Arts, Science, Commerce Stream Subject Wise Solved Question Bank for Hindi & English Medium Students with Exam Pattern & Blueprint and subject Wise with 11th & 12th Question Bank 2024 for General & Vocational Course Languages & Subjects Important Question for the above link.