Ruby, Rails and hash's with_indifferent_access

Long Names

Ruby developers like to be clear in their naming of variables, modules, classes, methods, and so on. I believe this comes from the idea that code should need very few inline comments if it is written clearly and descriptively. This descriptive naming strategy, combined with the decidedly non-English origins of Ruby (Japanese) and Rails (Danish), often result in oddly-named creations such as #execute_query_as_logged_in_user_without_transaction_logging (which I just made up), and #validates_numericality_of (which is real).

A newcomer might find these tongue-twisting, hyper-descriptive naming conventions maddening, but most of the time the intent becomes so much clearer as a result, it becomes infectious; in no time you find yourself writing your own 30-letter, borderline-semantically-correct method names and producing highly maintainable, readable, self-documenting code. That doesn't mean it happens all the time, though...

When I first ran across #with_indifferent_access I had no choice but to look it up as I had no hope of figuring out what it meant. "Indifferent" is how I feel when my wife asks me if I want chicken & snow peas or chicken & broccoli for dinner, not how I feel about ruby hashes. Admittedly, I was a little disappointed then to discover HashWithIndifferentAccess doesn't do much: it just extends a Hash so that you can retrieve values with either string or symbol keys. The Hash is "indifferent" as to which type of key you send it.

>> { :first => 'Kevin', :last => 'Hunt' }['last']
=> nil
>> require 'active_support' # Adds with_indifferent_access to Hash
=> true
>> { :first => 'Kevin', :last => 'Hunt' }.with_indifferent_access['last']
=> "Hunt"

This appears related to Hash#symbolize_keys, but also converts hashes within the hash.

>> { :name => { :first => 'Kevin', :last => 'Hunt' } }['name']['last']
NoMethodError: undefined method `[]' for nil:NilClass
        from (irb):4
>> { :name => { :first => 'Kevin', :last => 'Hunt' } }.with_indifferent_access['name']['last']
=> "Hunt"

Further Reading

Rails' HashWithIndifferentAccess docs

Feedback and Article Ideas

Want to see a topic explored here? Send Me a Message.