One of the coolest features of Ruby’s Hash class is that you can customize how it behaves when it can’t find a key. Stupid example:
# Everybody knows that you can communicate with foreigners by
# speaking loudly and slowly
english_to_french = Hash.new{|hash, key|
hash[key] = key.upcase.split(//).join(" ") + "?!"
}
english_to_french["restroom"] # => "R E S T R O O M?!"
One particularly useful application of this feature is to use a Hash as a cache for some slow operation. Here’s a snippet from Firetower, where a Hash is being used as a table of user accounts. If an unknown user ID is requested, the Hash makes a web service call to retrieve the requested data, stores it away, and returns it.
@users = Hash.new do |cache, user_id|
data = session.get(subdomain, "/users/#{user_id}.json")
cache[user_id] = data['user']
end
