From: "sawa (Tsuyoshi Sawada)" Date: 2022-05-25T12:02:48+00:00 Subject: [ruby-core:108694] [Ruby master Feature#14602] Version of dig that raises error if a key is not present Issue #14602 has been updated by sawa (Tsuyoshi Sawada). What about simply allowing `fetch` to take multiple arguments? If there are more than two arguments, always interpret the last one as the default value unless when there is a block, in which case, the block is evaluated if a key is missing somewhere in the path. You would need to explicitly write a block if you want to raise an error, but I believe your intention is not to let the raised error go through all the way to the top level to end the program; you intend to catch that error somewhere, and do something with it, right? Then, you can instead write that routine in the block from the beginning. (1) No change to present behavior: ```ruby hash.fetch(:name, :first) # => {:first => "Ariel", :last => "Caplan"} ``` (2) Perhaps error prone use cases, but these are suited for `dig`, so do not use `fetch` in practice in such cases, and it would not be a problem: ```ruby hash.fetch(:name, :first, nil) # => "Ariel" hash.fetch(:name, :middle, nil) # => `nil` ``` (3) Explicitly raise an error in a block: ```ruby hash.fetch(:name, :middle){|key| raise KeyError} ``` (4) Or, write a routine: ```ruby hash.fetch(:name, :middle){|key| process_missing_key(key)} ``` ---------------------------------------- Feature #14602: Version of dig that raises error if a key is not present https://bugs.ruby-lang.org/issues/14602#change-97739 * Author: amcaplan (Ariel Caplan) * Status: Open * Priority: Normal ---------------------------------------- Currently, if I have a hash like this: ~~~ ruby { :name => { :first => "Ariel", :last => "Caplan" } } ~~~ and I want to navigate confidently and raise a KeyError if something is missing, I can do: ~~~ ruby hash.fetch(:name).fetch(:first) ~~~ Unfortunately, the length of the name, combined with the need to repeat the method name every time, means most programmers are more likely to do this: ~~~ ruby hash[:name][:first] ~~~ which leads to many unexpected errors. The Hash#dig method made it easy to access methods safely from a nested hash; I'd like to have something similar for access without error protection, and I'd think the most natural name would be Hash#dig!. It would work like this: ~~~ ruby hash = { :name => { :first => "Ariel", :last => "Caplan" } } hash.dig!(:name, :first) # => Ariel hash.dig!(:name, :middle) # raises KeyError (key not found: :middle) hash.dig!(:name, :first, :foo) # raises TypeError (String does not have #dig! method) ~~~ -- https://bugs.ruby-lang.org/ Unsubscribe: