How do I use the fetch method for nested hash?

From Ruby 2.3.0 onward, you can use Hash#dig:

hash.dig('name', 'Mike', 'age')

It also comes with the added bonus that if some of the values along the way turned up to be nil, you will get nil instead of exception.

You can use the ruby_dig gem until you migrate.


EDIT: there is a built-in way now, see this answer.


There is no built-in method that I know of. I have this in my current project

class Hash
  def fetch_path(*parts)
    parts.reduce(self) do |memo, key|
      memo[key.to_s] if memo
    end
  end
end

# usage
hash.fetch_path('name', 'Mike', 'age')

You can easily modify it to use #fetch instead of #[] (if you so wish).


As of Ruby 2.3.0:

You can also use &. called the "safe navigation operator" as: hash&.[]('name')&.[]('Mike')&.[]('age'). This one is perfectly safe.

Using dig is not safe as hash.dig(:name, :Mike, :age) will fail if hash is nil.

However you may combine the two as: hash&.dig(:name, :Mike, :age).

So either of the following is safe to use:

hash&.[]('name')&.[]('Mike')&.[]('age')
hash&.dig(:name, :Mike, :age)

Tags:

Ruby