Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid NoMethodError for nil elements when accessing nested hashes? [duplicate]

If I try to access a hash element that isn't present, I get NoMethodError: undefined method '[]' for nil:NilClass. However, I can't predict which elements will be present.

@param_info = {}
@param_info["drug"]["name"]
# => NoMethodError: undefined method `[]' for nil:NilClass

How can I avoid raising this error when an element is unexpectedly nil?

like image 220
Rob Avatar asked Nov 21 '13 16:11

Rob


2 Answers

Ruby 2.3.0 introduced a new method called dig on both Hash and Array that solves this problem entirely.

It returns nil if an element is missing at any level of nesting.

h1 = {}
h2 = { a: {} }
h3 = { a: { b: 100 } }

h1.dig(:a, :b) # => nil
h2.dig(:a, :b) # => nil
h3.dig(:a, :b) # => 100

Your use case would look like this:

@param_info.dig('drug', 'name')
like image 73
user513951 Avatar answered Oct 23 '22 13:10

user513951


If I understand your question correctly i.e. make it forgiving in case an attribute value is missing, then you could try the following:

@param_info.try(:fetch, :drug).try(:fetch, :name)

This might return nil as well, but this will get rid of the error undefined methods '[]' for nil:NilClass

Update:

In order to handle keys that do not exist, you could try the following. (Got this hint from Equivalent of try for a hash):

@param_info.try(:[], :drug).try(:[], :name)
like image 40
vee Avatar answered Oct 23 '22 13:10

vee