The Yield Keyword in Ruby
source link: https://www.tuicool.com/articles/hit/qYNFfeY
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
My Ruby :love_letter: newsletter :love_letter: is available here ! Feel free to subscribe ! :rocket:
The Yield Keyword in Ruby
In this article, we’re going to explore the following topics:
Enumerable#map
The yield
keyword — in association with a block — allows to pass a set of additional instructions during a method invocation.
This mechanism allows you to customise a method depending on your needs.
What’s a block ?
A block is part of the Ruby method syntax.
This means that when a block is recognised by the Ruby parser then it’ll be associated to theinvoked method and literally replaces the yield
s in the method
produces
one yield multiple yields multiple yields
The code inside the block will literally replace the yield
keyword in the method definition.
Now, what happens if we don’t pass a block during method invocation for a method that includes a yield
?
block_given?
When yield
is called in a method then the method requires a block. Otherwise, a LocalJumpError
is raised
So, how to make the block optional ? The answer is by using the Kernel#block_given?
method
Arguments
yield
can take a list of arguments that will be available for the block
Here, the block takes the arguments |hello, world|
that are provided by the yield
inside the yield_with_arguments
method.
Return value
It’s possible to get the return value of a block by simply assigning the return value of a yield
to a variable
The hello_world
variable get the "Hello World!"
returned by the block and display it by using puts
.
Array#my_map
Now that we’ve made an overview of yield
and blocks, let’s try to recap the important notions by implementing an example.
The Enumerable#map
method allows you to iterate over a list of objects and manipulate each of them. Then it’ll return a new list that contains all the manipulated objects.
$> array = [1, 2, 3]
=> [1, 2, 3]
$> array.map {|n| n + 2}
=> [3, 4, 5]
$> array
=> [1, 2, 3]
In the above example, we assign [1, 2, 3]
to the array
variable.
Then we call the array.map {|n| n + 2}
that adds 2
to each element of the array
. a new array that contains [3, 4, 5]
is returned by the map
method.
Finally, we see that the initial array
didn’t change.
Now, let’s try to implement our own version of Enumerable#map
directly on the Array
class
$> array = [1, 2, 3]
=> [1, 2, 3]
$> array.my_map {|n| n + 2}
=> [3, 4, 5]
$> array
=> [1, 2, 3]
Our custom method has the same behaviour as the Enumerable#map
method.
That’s great ! Now let’s dive in the code.
1- we create a temporary Array
named ary
. This variable will contain the return value of our method.
2- we iterate over the receiver Array
by using self.each
.
3- for each element, we call yield(elem)
— where elem
is the current element of the iteration. Then, we store the return value of the yield(elem)
in the ary
variable.
4- we return ary
.
Now, what happens if we don’t pass a block to our Array#my_map
method?
$> array.my_map
LocalJumpError (no block given (yield))
As you probably expected, an error is raised.
But fortunately, we’ve already fixed this issue in the previous sections.
So let’s reuse the Kernel#block_given?
method to enhance our Array#my_map
method
$> array.my_map
=> [1, 2, 3]
If there is no block passed to the method then we force the method to return a copy of the receiver array.
Voilà !
Thank you for taking the time to read this post :-)
Feel free to :clap: and share this article if it has been useful for you.
My Ruby :love_letter: newsletter :love_letter: is available here ! Feel free to subscribe ! :rocket:
Here is a link to my last article: A matter of Attributes
.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK