winfred.nadeau

Great software speaks for itself.

Unobtrusive Dot Hash Access

originally written March 24, 2012
I'm a big fan of javascript, but just love the zen of ruby. Other tradeoffs aside, I really wish I could access hash values in ruby using the dot notation that reads so well with javascript object literals. Four characters (two brackets and two quotes) could be reduced to a simple dot. I've been writing and consuming more JSON APIs in my ruby projects lately, so I decided to monkey patch that crap despite the warning in my mind against mucking up a standard lib class. "Why not just use an OpenStruct?" Of course this was my first question, but even storing a JSON response as a serialized open-struct does not convert the Hashes inside the OpenStruct to OpenStructs, so simply converting an API response to an OpenStruct will not automatically convert the children accordingly. While there are some sort of hacky solutions to this problem, such as the RecursiveOpenStruct gem, implementation was buggier than expected and there is the pervasive 'what about memory consumption' question. (A valiant attempt to provide a more complete solution than this, though!) So I decided to crack open the Hash class and dive on in, damn the consequences. The result? As with any time one sticks their dirty fingers into a standard library class, you gotta be sure you don't cross any beams or cut red wires. So, this little monkey patch aims to be as unobtrusive as possible. There are, of course, some drawbacks.
  1. Keys can only be read and updated. They can not be created through dot-access.
  2. Public methods of the Hash class get priority, so if there is a key named 'length', calling my_hash.length will not be able to access that key's value. It will instead call the Hash#length method.
  3. String keys will be checked first, so if your hash contains a symbol key and a string key of the same name, you wouldn't be able to access the symbol value through dot.key access. (kind of like a HashWithIndifferentAccess)
For my use case at least, storing/accessing/consuming JSON apis, these drawbacks mean very little for the readability gained, and using dot method is entirely optional. For any subclasses of Hash, this should provide them similar functionality. Unless of course they override method_missing in a new way, in which case it probably didn't want this functionality anyway. So far at least, I haven't encountered a situation where this monkeypatch breaks something, so perhaps it might be gem-worthy so long as one knows how to use it. I can't help but feel like I'm missing something though, as if the ghost of this monkey will come back to haunt me. I think I'm willing to take that risk so I can keep eating my dot hash cereal.