December 12, 2017
This blog is part of our Ruby 2.5 series.
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.
irb> "Hello".yield_self { |str| str + " World" }
=> "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.
irb> "Hello".try { |str| str + " World" }
=> "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.
irb> nil.yield_self { |obj| "Hello World" }
=> "Hello World"
irb> nil.try { |obj| "Hello World" }
=> 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.
irb> "Hello".yield_self { |str| str + " World" }
=> "Hello World"
irb> "Hello".tap { |str| str + " World" }
=> "Hello"
Overall, yield_self improves readability of the code by promoting chaining
over nested function calls. Here is an example of both the styles.
irb> add_greeting = -> (str) { "HELLO " + str }
irb> to_upper = -> (str) { str.upcase }
# with new `yield_self`
irb> "world".yield_self(&to_upper)
.yield_self(&add_greeting)
=> "HELLO WORLD"
# nested function calls
irb> add_greeting.call(to_upper.call("world"))
=> "HELLO WORLD"
yield_self is part of Kernel and hence it's available to all the objects.
If this blog was helpful, check out our full blog archive.