A ruby test for nil throws an error
- x is an Array.
- Notice the two comparisons below. The first should produce "true", as expected. The second throws an error. What is going on here?
Why does negative comparison for nil not produce false in the second test?
ruby-1.9.2-p136 :079 > x[2]['comments']['data'][0]['from']['name'] != nil
=> true
x[2]['comments']['data'][1]['from']['name'] != nil
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
from (irb):78
from /Users/justinz/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/commands/console.rb:44:in `start'
from /Users/justinz/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/commands/console.rb:8:in `start'
from /Users/justinz/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/commands.rb:23:in `<top (required)>'
开发者_如何学Pythonfrom script/rails:6:in `require'
from script/rails:6:in `<main>'
I'd guess it's because the value x[2]['comments']['data'][1]
is nil.
You might want to use this helper method instead:
def nullsafe_index(a, keys)
keys.each{|key|
return nil if a.nil?
a = a[key]
}
return a
end
Use like this:
nullsafe_index(x, [2, 'comments', 'data', 0, 'from', 'name']).nil?
x[2]['comments']['data'][1] is an empty hash, so when you call ['from'] on it, the result is nil, which means calling ['name'] on that result of nil, produces an error. Here's how you can reproduce it:
x = {}
x['from'] #=> nil
x['from']['name'] #=> NoMethodError
You can think of your request as a collection of function calls:
x[2]['comments']['data'][1]['from']['name']
# is equivalent to:
x.[](2).[]('comments').[]('data').[](1).[]('from').[]('name')
If any one of these function calls returns nil you can't make another [] function call on it without getting an error.
It looks like x[2]['comments']['data']
doesn't have a second element. This is equivalent to calling nil['from']
, which will also raise an exception.
Is x[2]['comments']['data'][1] == nil
?
Try evaluating each piece of your expression:
x[2]
x[2]['comments']
x[2]['comments']['data']
x[2]['comments']['data'][1]
x[2]['comments']['data'][1]['from']
x[2]['comments']['data'][1]['from']['name']
精彩评论