Project

General

Profile

Feature #13179

Deep Hash Update Method

Added by bettisworth (wurde _) about 2 years ago. Updated over 1 year ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:<unknown>]

Description

I came across a scenario where I needed the ability to update a deeply nested hash (Rails i18n yaml files). This seemed like something that would exist naturally in the DSL of ruby, but I could only find dig() method which only retrieves values if they exist. 24 hours later I wrote a update_deep_hash method (I wouldn't wish this type of recursive coding on anyone else within the Ruby community).

Attached is the solution I hacked together. My question is if we can have a Hash.dig() method which reaches into a deep hash can we expand on this to include update methods of similar nature?


Files

update_deep_hash.rb (2.26 KB) update_deep_hash.rb bettisworth (wurde _), 02/01/2017 06:45 PM

Related issues

Is duplicate of Ruby trunk - Feature #11747: "bury" feature, similar to 'dig' but opposite RejectedActions

History

Updated by nobu (Nobuyoshi Nakada) about 2 years ago

  • Status changed from Open to Feedback
  • Tracker changed from Bug to Feature

dig is not only for Hash but also for Array, Struct, and OpenStruct.
What objects would you expect as intermediate containers if not present?

Regarding the name, bury occurred to me.
Hash#dig= might fit if obj.method(arg,...) = val syntax were possible.

Updated by shevegen (Robert A. Heiler) about 2 years ago

Regarding the name, bury occurred to me.

.dig and .bury - I can already feel on Halloween the .zombies() coming up!

Updated by bettisworth (wurde _) about 2 years ago

Any method name four or less characters long is a big win. Using bury would be much nicer than my current update_deep_hash calls.

I wasn't aware of dig in the other classes. I may be overlooking something but why not just use the class dig is used on as a container? Another way would be to allow setting the default container via an optional argument like when setting default values for a Hash, Array, and so on.

#4

Updated by nobu (Nobuyoshi Nakada) about 2 years ago

  • Is duplicate of Feature #11747: "bury" feature, similar to 'dig' but opposite added

Updated by shyouhei (Shyouhei Urabe) about 2 years ago

This is possible in perl:

use strict;
use warnings;
use Data::Dumper qw(Dumper);

my %hash = qw();
$hash{q}{w}{e}{r}{t} = 'y';

warn(Dumper(\%hash));

From perl's POV it seems ruby lacks this feature.

Updated by matz (Yukihiro Matsumoto) about 2 years ago

  • Status changed from Feedback to Rejected

It's no difference from #11747. You have to come up with a better name candidate and concrete use-case.

Matz.

Updated by MarioRuiz (Mario Ruiz Sánchez) over 1 year ago

bettisworth (wurde _) wrote:

I came across a scenario where I needed the ability to update a deeply nested hash (Rails i18n yaml files). This seemed like something that would exist naturally in the DSL of ruby, but I could only find dig() method which only retrieves values if they exist. 24 hours later I wrote a update_deep_hash method (I wouldn't wish this type of recursive coding on anyone else within the Ruby community).

Attached is the solution I hacked together. My question is if we can have a Hash.dig() method which reaches into a deep hash can we expand on this to include update methods of similar nature?

What I am using in my code is a simple bury method... at least for the best cases is working nice:

#my_hash.bury([:accent,2,:original],"the value to set")
class Hash
  def bury(where, value)
      me=self
      where[0..-2].each{|key|
        me=me[key]
      }
      me[where[-1]]=value
  end
end

#my_array.bury([2,1,:original],"the value to set")
class Array
  def bury(where, value)
      me=self
      where[0..-2].each{|key|
        me=me[key]
      }
      me[where[-1]]=value
  end
end

Also available in: Atom PDF