There is a Ruby best practices blog that is exploring the uses of Object#tap, particularly with respect to building hashes, as per the example they give:
def ugly results = {} [:x, :y, :z].each do |letter| results[letter] = rand(100) end results end
def sexy returning({}) do |results| [:x, :y, :z].each do |letter| results[letter] = rand(100) end end end
There is a lot of commentary as to which of the two is better. But in programming there is always another way! In code we are building a hash from an array. This is exactly the kind of thing Ruby’s Enumerable#inject method is for. Some of the commenteres on the blog have pointed this out.
def very_sexy [:x, :y, :z].inject({}) do |results, letter| results[letter] = rand(100) results end end
I use this often enough to write a method for the tedious aspects of having to return the hash
module Enumerable def inject_hash(hash = {}) inject(hash) {|(h,item)| yield(h,item); h} end end
def smokin [:x, :y, :z].inject_hash do |results, letter| results[letter] = rand(100) end end
I am excited about the inclusion of Object#tap in Ruby 1.9, but it should be used mostly as a debugging tool or to overcome poorly designed interfaces. Frequent use in your own code could be a code smell.