“...I've been working since 2008 with Ruby / Ruby on Rails, love a bit of Elixir / Phoenix and learning Rust. I also poke through other people's code and make PRs for OpenSource Ruby projects that sometimes make it. Currently working for InPay who are based in Denmark...”

Rob Lacey
Senior Software Engineer, UK

Ruby #tap

Bit of Ruby fun. I really like #tap for cleaning up blocks where you assign unnecessary variables. While I admit the following examples don’t all do the same thing I noticed something this morning. The first two should have concatenated the Array and last one oappended. It’s odd that the first two examples returned an empty Array and not [1, 1, 2, 3], or [[1 ], [1, 2, 3]]

2.2.6 :018 > [].tap { |a| a += [1]; a += [1,2,3] }
 => [] 
2.2.6 :018 > [].tap { |a| a += [[1]]; a += [[1,2,3]] }
 => [] 
2.2.6 :019 > [].tap { |a| a << [1]; a << [1,2,3] }
 => [[1], [1, 2, 3]]

So, the object returned from #tap is always the one you passed in, so for a start is doesn’t return that last thing evaluated in the block. Then you realise a += 1 returns a new object and reassigns the value of a, so it can’t be the original object and therefore you’re concatenating and creating a new object that isn’t returned.