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"

How is it different from 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

What about 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"