Unobtrusive Dot Hash Access
originally written March 24, 2012
"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.
- Keys can only be read and updated. They can not be created through dot-access.
- 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.
- 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.