alex_dugger $>

Nil as a Hash Key

02 Oct 2015

I was doing a little code review with a teammate and one of his hash definitions caught my eye. It looked something like this…

hsh = {
  :foo => Foo,
  :bar => Bar,
  nil  => Qux
}

This had nothing to do with our conversation, but… ‘nil’? “Can you really use ‘nil’ as a Hash key?” I asked. Apparently you can. After all (as Sandi Metz taught us) nothing IS something. So, I tried it, and sure enough, it works. You can use the ‘active nothing’ in this way.

k1 = method_that_might_return_a_symbol()
#=> :foo
hsh[k1].new
#=> #<Foo:0x007fc8b203b970>
key = method_that_might_return_a_symbol()
#=> nil
hsh[key].new
#=> #<Qux:0x007fc8b203b970>

Now, I’m not sure there is a huge use case for this, but it is cleaner than writing a condition to ensure the Hash has a value before calling it, so it might have some uses.

hsh[key].new if hsh[key]

However, this doesn’t let you get around passing a key.

hsh[]
#=> ArgumentError: wrong number of arguments (0 for 1)

That is, unless you do this first…

class Hash
  SETTER = Hash.instance_method(:[]=)
  GETTER = Hash.instance_method(:[])
  def []=(key=nil, value)
    SETTER.bind(self).call(key, value)
  end
  def [](key=nil)
    GETTER.bind(self).call(key)
  end
end

…but you should probably never do that.