Skip to content

Instantly share code, notes, and snippets.

@jmmastey
Last active March 15, 2021 23:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jmmastey/7c48e838d2f4fb3aa165278eb174e08e to your computer and use it in GitHub Desktop.
Save jmmastey/7c48e838d2f4fb3aa165278eb174e08e to your computer and use it in GitHub Desktop.
christmas_movies = {
die_hard: { violence: true, cheer: true },
nightmare: { violence: false, cheer: 'who knows' }
}
# if I'm just digging one layer into the hash, I don't get an error,
# I just get nil.
christmas_movies[:die_hard] # => { violence: true, cheer: true }
christmas_movies[:home_alone_3] # => nil
# but when I need to dig deeper, here I get the error
christmas_movies[:die_hard][:violence] # => true
christmas_movies[:home_alone_3][:violence] # NoMethodError
# to understand why this is, break out the parts of that code above:
movie_deets = christmas_movies[:home_alone_3]
movie_deets[:violence]
# or since we know the deets are nil...
nil[:violence]
# which of course doesn't work, because `nil` doesn't implement `[]`. but this
# sort of thing is super common, so folks decided to invent a method that could
# do hash stuff, but wouldn't ever throw an error. that's the big difference:
# hash#dig is _guaranteed_ not to error because of missing keys
christmas_movies.dig(:die_hard, :violence) # => true
christmas_movies.dig(:home_alone_3, :violence) # => nil
# it's cool for when you have nested hashes and you don't _care_ if a key is
# missing. you'll just get a nil and move along.
last_ip = some_facebook_response.dig(:user, :last_login, :ip_address)
# but that is also a double-edged sword. it can be really hard to understand
# why your code broke when you make a typo. in this code, it might be hard to
# see that "profile" is misspelt. it just looks like the data is always empty.
city = some_facebook_response.dig(:user, :profilee, :address, :city)
# even if I spelled this right, if facebook started returning primary_address
# instead of address, the code would fail silently.
# so overall, if you're going to chain together sets of brackets, dig is nice
# for guaranteeing that you won't error. it's just also a bit squicky if you
# don't really really control the data as it comes in.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment