Last Updated: February 25, 2016
·
332
· Rodreegez

Hash.new

Ruby Hashes can do some pretty cool things, depending how you create them.

>> h = Hash.new
=> {}
>> h[:foo]
=> nil
>> h.keys
=> []

Ok, nothing crazy there. Hash.new can take a value, which will become the default value returned if a key isn't found in the hash.

>> h = Hash.new('bacon')
=> {}
>> h[:foo]
=> "bacon"
>> h.keys
=> []

Alright, pretty cool. Not quite sure why you might want to do that, but I guess it's a good way to avoid the dreaded nil. We can use this construct to create a cheap counter.

>> h = Hash.new(0)
=> {}
>> h[:foo]
=> 0
>> h[:foo] += 1
=> 1
>> h.keys
=> [:foo]
>> h[:foo] += 1
=> 2
>> h[:foo] += 1
=> 3
>> h[:foo]
=> 3

Pretty cool. What next? How about a block? The arguments (?) to the block represent the hash itself (h) and the key being accessed (k). We can use this to create a hash that will automatically populate itself with the value of the key being called.

>> h = Hash.new { |h,k| h[k] = k }
=> {}
>> h['foo']
=> "foo"
>> h.keys 
=> ["foo"]
>> h['foo']
=> "foo"
>> h.keys
=> ["foo"]

Ok, not very useful, but what if we set the value of the key to fetch the key as an HTTP request?

>> require 'httparty'
=> true
>> h = Hash.new { |h,k| h[k] = HTTParty.get(k).body }
=> {}
>> h['http://rodreegez.com']
=> # takes a while, but returns the HTML of my personal site
>> h['http://rodreegez.com']
=> # returns instantly the same HTML

Boom. The cheapest caching construct available to man. Maybe. I urge you to try that last one. It's probably useless but kinda fun.

I hope you keep this in mind next time you are using a hash. It can come in handy!

I pinched most of the above from here: http://endofline.wordpress.com/2010/12/24/hash-tricks/