Dive: for deep hash access

Dive is a gem for accessing values within nested Hashes.

Why?

Well, it all started when I was mapping human readable names taken from a Cucumber table to fields in a JSON response:

Given I have some sausages with
  | Name          | Contents                      |
  | Pork + Fennel | pork mince, fennel, intestine |
  | Soylent Green | people                        |  
Given /^I have some sausages with$/ |table|
  fields = {
    'Name' => :name,
    'Contents' => :ingredients
  }
  table.hashes.each do |row|
    sausage = {} 
    row.each_pair do |key, value|
      sausage[fields[key]] = value
    end
    @response[:sausages] << sausage
  end
end
@response
{ 
  :sausages => [
    {
      :name => 'Pork + Fennel'
      :ingredients => 'pork mince, fennel, intestine'
    },
    {
      :name => 'Soylent Green',
      :ingredients => 'people'
    }
  ]
}

All fine and dandy until I had to map to values that were nested under the first level of the response:

@response
{ 
  :sausages => [
    {
      :name => 'Pork + Fennel'
      :ingredients => {
        :casing => 'intestine',
        :filling => {
          :meat => 'pork mince',
          :spices => 'fennel'
        }
      }
    }
  ]
}

I wanted to be able to do something like this:

fields = {
  'Name' => :sausage_name,
  'Spices' => ':ingredients[:filling[:spices]]'
}

So I did.

Check out the specs for how it behaves.

Dive has been tested with ruby 1.9.2 and 1.8.7.

Installation and usage

gem install dive

require 'dive'
foods = { :sausages => {:pork_and_fennel => 'DELICIOUS'}}
foods[':sausages[:pork_and_fennel]']

Or if you become squeamish at the idea of overriding Hash's [] method:

require 'dive/noninvasive'
foods.dive ':sausages[:pork_and_fennel]'

A Note on Dive Keys

Anything containing square brackets can be parsed as a Dive key, for example

'first[second]'

If you are experiencing strange behaviour while using dive to override Hash methods, please check that none of your keys are unintentionally being recognised as such. A test case for the unusual ones would be much appreciated.