Project

General

Profile

Actions

Feature #15563

open

#dig that throws an exception if a key doesn't exist

Added by 3limin4t0r (Johan Wentholt) about 5 years ago. Updated about 4 years ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:91265]

Description

Ruby 2.3.0 introduced #dig for Array, Hash and Struct. Both Array and Hash have #fetch, which works the same way as #[], but instead of returning the default value, raises an exception (unless a second argument or block is given). Hash also has #fetch_values, which works the same way as #values_at, raising an exception if a key is missing. For #dig, there is no such option.

My proposal is to add a method that works the same way as #dig, but instead of using the #[] accessor, uses #fetch.

This method would look something like this:

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).

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 and the method name.


Related issues 2 (2 open0 closed)

Is duplicate of Ruby master - Feature #12282: Hash#dig! for repeated applications of Hash#fetchOpenActions
Is duplicate of Ruby master - Feature #14602: Version of dig that raises error if a key is not presentOpenActions
Actions

Also available in: Atom PDF

Like1
Like0Like0Like0Like0Like0Like1Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0