Project

General

Profile

Actions

Feature #13179

closed

Deep Hash Update Method

Added by bettisworth (wurde _) almost 8 years ago. Updated over 5 years ago.

Status:
Rejected
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 2 (0 open2 closed)

Related to Ruby master - Feature #19699: Need a way to store values like digClosedActions
Is duplicate of Ruby master - Feature #11747: "bury" feature, similar to 'dig' but opposite Rejectedmatz (Yukihiro Matsumoto)Actions

Updated by nobu (Nobuyoshi Nakada) almost 8 years ago

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

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) almost 8 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 _) almost 8 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.

Actions #4

Updated by nobu (Nobuyoshi Nakada) over 7 years ago

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

Updated by shyouhei (Shyouhei Urabe) over 7 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) over 7 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) almost 7 years 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

Updated by bkatzung (Brian Katzung) over 5 years ago

Gem XKeys, since 2014.

require 'xkeys'
h = {}.extend XKeys::Auto # auto Hash/Array
h[:accent, 2, :original] = "the value to set"
# {:accent=>[nil, nil, {:original=>"the value to set"}]}

h = {}.extend XKeys::Hash # Hash only
h[:accent,2,:original]='the value to set'
# {:accent=>{2=>{:original=>"the value to set"}}}

a = [].extend XKeys::Auto
a[2, 1, :original] = "the value to set"
# [nil, nil, [nil, {:original=>"the value to set"}]]
a[2, 1] # (slice 2, 1) [[nil, {:original=>"the value to set"}]]
a[2, 1, {}] # (a[2][1]) {:original=>"the value to set"}
Actions #9

Updated by byroot (Jean Boussier) over 1 year ago

  • Related to Feature #19699: Need a way to store values like dig added
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0