Feature #15563
Updated by 3limin4t0r (Johan Wentholt) about 5 years ago
Ruby 2.3.0 introduced `#dig` for *Array*, *Hash* and *Struct*. Both *Array* and *Hash* have `#fetch` which does the same as `#[]`, but instead of returning the default value an exception is raised (unless a second argument or block is given). *Hash* also has `#fetch_values` which does the same as `#values_at`, raising an exception if an key is missing. For `#dig` there is no such option. My proposal is to add a method which does the same as `#dig`, but instead of using the `#[]` accessor it uses `#fetch`. This method would look something like this: ```Ruby module Traversable def traverse(key, *others) value = fetch(key) return value if others.empty? if value.respond_to?(__method__, true) value.send(__method__, *others) else raise TypeError, "#{value.class} does not have ##{__method__} method" end end end Array.include(Traversable) Hash.include(Traversable) ``` The exception raised is taken from `#dig` (`[1].dig(0, 1) #=> TypeError: Integer does not have #dig method`). ```Ruby yaml = YAML.load_file('some_file.yml') # this change is meant to make chaining #fetch calls more easy yaml.fetch('foo').fetch('bar').fetch('baz') # would be replaced with yaml.traverse('foo', 'bar', 'baz') ``` I'm curious to hear what you guys think about the idea as a whole whole, the method name and the method name. two points described above.