18

I've read about what tap does in Ruby but I'm confused by the code block below,

{}.tap do |h|
  # some hash processing
end

any help would be greatly appreciated.

Daniël Knippers
  • 3,049
  • 1
  • 11
  • 17
Subash
  • 3,128
  • 6
  • 30
  • 44

4 Answers4

28

#tap method simply passes an object it was called on to a block. At the end of the block it returns the same object again. This way you can chain operations or restrict variable scope.

{}.tap { |h| h[:a] = 1 }.size # => 1

You were able to chain a next method to this block. And also avoided creating a h variable in your scope.

Nikita Chernov
  • 2,031
  • 16
  • 13
  • 2
    Note that `symbolize_keys` is only available through Rails, not in regular Ruby. It also seems unnecessary in your example so perhaps just rewrite it to `h[:a] = 1` if you want a symbol key. – Daniël Knippers Aug 27 '14 at 10:02
  • You are right, that was for the sake of showing method chaining, of course – Nikita Chernov Aug 27 '14 at 10:41
17

tap is particularyl useful if you want to do some modifications on the hash and after that return it, e.g. inside a method that returns the hash. The advantage of tap being that you don't have to explitely return the hash at the end and there's no need for an intermediary variable.

hash = {}
hash[:a] = 'b'
hash
# => {:a=>"b"}

vs.

{}.tap do |hash|
  hash[:a] = 'b'
end
# => {:a=>"b"}
koffeinfrei
  • 1,985
  • 13
  • 19
  • But is there any point in using tap over using `{ :a => :b }` or `{ a: :b }` explicitly? UPD: Ah, I have found a usage - you can use key-value pairs defined first in later key-value pairs' definition, like this: `{}.tap { |hash| hash[:a] = 'b'; hash[:c] = hash[:b] + 'd' }` – rakvium Jul 28 '21 at 08:24
5

For exemple : you want to chain delete and each on a hash.

You cannot do

hash.delete(:key).each {...}

but can do

hash.tap { |h| h.delete(:key) }.each { ... }

It is a good way to chain your methods.

spickermann
  • 100,941
  • 9
  • 101
  • 131
Arthur
  • 181
  • 2
  • 10
2

tap doesn't do anything to it. Whatever you do to h in the block is whatever is done to the original {}.

sawa
  • 165,429
  • 45
  • 277
  • 381