Feature #13179
closedDeep Hash Update Method
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
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.
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"}
Updated by byroot (Jean Boussier) over 1 year ago
- Related to Feature #19699: Need a way to store values like dig added