Has this ever happened to you?
You have a json
structure that gets converted into a hash. It has a structure that's a variation on this:
{
'product': {
'title': 'Light saber',
'type': 'weapon',
'price': {
'value': 1000,
'currency': 'Imperial credits'
}
}
}
Say we want to extract the value
attribute from the last level of nesting, so we do:
response[:product][:price][:value] # ~> NoMethodError: undefined method `[]' for nil:NilClass
# =>
# ~> NoMethodError
# ~> undefined method `[]' for nil:NilClass
# ~>
# ~> xmptmp-in2891u-0.rb:8:in `<main>'
But it blows up. So either the :product
or :price
key is missing, but at this point we don't know which one. So we check for both
response[:product] && response[:product][:price] && response[:product][:price][:value]
# => nil
And it works, but it's very ugly.
There has to be another way!
Luckily, there is: The Hash#dig
method. This method accepts a succession of keys to navigate though and it returns the value at the end, except that if any of the intermediate keys is missing, it will stop the scan and return nil
.
response = {
product: {
title: 'Light saber',
type: 'weapon',
price: {
value: 1000,
currency: 'Imperial credits'
}
}
}
response.dig(:product, :price, :value)
# => 1000
response = {
product: {
title: 'Light saber',
type: 'weapon',
}
}
response.dig(:product, :price, :value)
# => nil
I use it all the time at work and hope you're using it too.
See you on the next one.
Saluti.