DigBang
Here’s Hash#dig! and Array#dig!. They're similar to Ruby’s Hash#dig and Array#dig, but they raise an exception instead of returning nil when a key isn’t found.
In a hash:
require 'dig_bang'
places = {
world: {
uk: true,
usa: true
}
}
# No difference when the key exists
places.dig :world, :uk # true
places.dig! :world, :uk # true
# A relevant error when the key is missing
places.dig :world, :uk, :alaska # nil
places.dig! :world, :uk, :alaska # KeyError: Key not found: :alaskaIn an array:
airports = %w(lhr sfo nyc)
# Same result when the index is valid
airports.dig 2 # 'nyc'
airports.dig! 2 # 'nyc'
# A relevant error when the index is out of bounds
airports.dig 5 # nil
airports.dig! 5 # IndexError: index 5 outside of array bounds: -3...3In a mixed data structure:
places = {
world: {
uk: %w(lhr lgw man stn),
usa: %w(nyc pdx sfo dca)
}
}
places.dig :world, :usa, 2 # 'sfo'
places.dig! :world, :usa, 2 # 'sfo'
places.dig :world, :usa, 4 # nil
places.dig! :world, :usa, 6 # IndexError: index 6 outside of array bounds: -4...4In combination with #dig:
places.dig!(:world, :usa).dig(6) # nilThe philosohy
#dig! is to #fetch as #dig is to #[]
Ruby 2.3 introduces the new Hash#dig method for safe extraction of a nested value. It’s the equivalent of a safely repeated Hash#[].
#dig!, on the other hand, is the equivalent of a safely repeated Hash#fetch. It’s “safely unsafe”😉 raising the appropriate KeyError anywhere down the line, or returning the value if it exists.
It's also just 18 lines of code.
Installation
Add this line to your application's Gemfile:
gem 'dig_bang'And then execute:
$ bundle
Or install it yourself as:
$ gem install dig_bang