Project

General

Profile

Actions

Feature #21545

open

#try_dig, a dig that returns early if it cannot dig deeper

Added by cb341 (Daniel Bengl) about 10 hours ago. Updated about 10 hours ago.

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

Description

Ruby offers dig for traversing nested hashes and arrays. It is strict and will raise if an intermediary object does not support dig. In many cases we only want to attempt the lookup and return nil if it cannot be followed, without caring about the exact reason.

Example:

{ a: "foo" }.dig(:a, :b)
# TypeError: String does not have #dig method

{ a: "foo" }.try_dig(:a, :b)
# => nil

This is especially useful when dealing with data from APIs or other inconsistent sources:

api_response = { status: "ok" }
api_response.try_dig(:status, :code) # => nil

api_response = { status: { code: 200 } }
api_response.try_dig(:status, :code) # => 200

The name try_dig makes it clear that it behaves like dig but will never raise for structural mismatches.
It complements dig and the proposed dig! (#12282, #15563) by covering the tolerant lookup case.

A possible sketch:

class Object
  def try_dig(*path)
    current = self
    path.each do |key|
      return nil unless current.respond_to?(:dig)
      begin
        current = current.dig(key)
      rescue StandardError
        return nil
      end
    end
    current
  end
end

I initially proposed this in Ruby core (PR #14203) and even implemented it in C, but later realized that if this gets introduced at all it probably makes more sense to have it in ActiveSupport rather than in core Ruby.

Advantages

  • Simplifies tolerant lookups without repetitive rescue logic
  • Clear intent when the value is optional
  • Useful for working with inconsistent or partially known data structures
  • Complements dig and potential dig! by covering the tolerant case

Disatvantages

  • May hide structural issues that should be noticed during development
Actions #1

Updated by cb341 (Daniel Bengl) about 10 hours ago

  • Description updated (diff)
Actions #2

Updated by cb341 (Daniel Bengl) about 10 hours ago

  • Description updated (diff)
Actions #3

Updated by cb341 (Daniel Bengl) about 10 hours ago

  • Subject changed from `#try_dig`: a dig that returns early if it cannot dig deeper to #try_dig, a dig that returns early if it cannot dig deeper
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0