We write about Ruby on Rails, React.js, React Native, remote work, open source, engineering and design.
Ruby 2.5 added a new method named yield_self. It yields the receiver to the given block and returns output of the last statement in the block.
1irb> "Hello".yield_self { |str| str + " World" }
2 => "Hello World"
try
in Rails ?Without a method argument
try
behaves similar to yield_self
.
It would yield to the given block
unless the receiver is nil
and returns the output of the last statement in the block.
1irb> "Hello".try { |str| str + " World" }
2 => "Hello World"
Couple of differences to note are,
try
is not part of Ruby
but Rails
.
Also try
's main purpose is protection against nil
hence it doesn't execute the block if receiver is nil
.
1irb> nil.yield_self { |obj| "Hello World" }
2 => "Hello World"
3
4irb> nil.try { |obj| "Hello World" }
5 => nil
tap
?tap
also is similar to yield_self
.
It's part of Ruby itself.
The only difference is the value that is returned.
tap
returns the receiver itself
while yield_self
returns the
output of the block.
1irb> "Hello".yield_self { |str| str + " World" }
2 => "Hello World"
3
4irb> "Hello".tap { |str| str + " World" }
5 => "Hello"
Overall, yield_self
improves readability of the code
by promoting chaining
over nested function calls.
Here is an example of both the styles.
1irb> add_greeting = -> (str) { "HELLO " + str }
2irb> to_upper = -> (str) { str.upcase }
3
4# with new `yield_self`
5irb> "world".yield_self(&to_upper)
6 .yield_self(&add_greeting)
7 => "HELLO WORLD"
8
9# nested function calls
10irb> add_greeting.call(to_upper.call("world"))
11 => "HELLO WORLD"
12
yield_self
is part of Kernel
and
hence it's available to all the objects.