Feature #5531
closeddeep_value for dealing with nested hashes
Description
This feature request stems from dealing with nested hashes, like the params from a request often dealt with in web frameworks.
Conditional code often needs to be written with multiple logical ANDs in order to achieve what this simple function can:
class Hash
def deep_value(*ks)
if ks.size == 1
return self[ks.shift]
else
val = ks.shift
return (self[val].is_a?(Hash) ? self[val].deep_value(*ks) : nil)
end
end
alias dv deep_value
end
deep_value (dv) will simply recurse over a hash given a set of indexes and return the value at the end.
Example:
foo = {:bar => {:baz => 'blah'}}
foo.dv(:bar, :baz)
-> 'blah'
foo.dv(:cats)
-> nil
Updated by ko1 (Koichi Sasada) about 13 years ago
(2011/11/01 8:52), Kyle Peyton wrote:
Example:
foo = {:bar => {:baz => 'blah'}}
foo.dv(:bar, :baz)
-> 'blah'
foo.dv(:cats)
-> nil
Just idea.
How about to extend Hash#[] for it?
--
// SASADA Koichi at atdot dot net
Updated by rkh (Konstantin Haase) about 13 years ago
What's the difference (usability wise) between
hash[:foo][:bar]
and
hash.dv(:foo, :bar)
Konstantin
On Oct 31, 2011, at 16:52 , Kyle Peyton wrote:
Issue #5531 has been reported by Kyle Peyton.
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531Author: Kyle Peyton
Status: Open
Priority: Normal
Assignee:
Category:
Target version:This feature request stems from dealing with nested hashes, like the params from a request often dealt with in web frameworks.
Conditional code often needs to be written with multiple logical ANDs in order to achieve what this simple function can:
class Hash
def deep_value(*ks)
if ks.size
Updated by rkh (Konstantin Haase) about 13 years ago
What's the difference (usability wise) between
hash[:foo][:bar]
and
hash.dv(:foo, :bar)
Konstantin
On Oct 31, 2011, at 16:52 , Kyle Peyton wrote:
Issue #5531 has been reported by Kyle Peyton.
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531Author: Kyle Peyton
Status: Open
Priority: Normal
Assignee:
Category:
Target version:This feature request stems from dealing with nested hashes, like the params from a request often dealt with in web frameworks.
Conditional code often needs to be written with multiple logical ANDs in order to achieve what this simple function can:
class Hash
def deep_value(*ks)
if ks.size
Updated by rkh (Konstantin Haase) about 13 years ago
Never mind, got it.
On Oct 31, 2011, at 17:32 , Haase, Konstantin wrote:
What's the difference (usability wise) between
hash[:foo][:bar]
and
hash.dv(:foo, :bar)
Konstantin
On Oct 31, 2011, at 16:52 , Kyle Peyton wrote:
Issue #5531 has been reported by Kyle Peyton.
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531Author: Kyle Peyton
Status: Open
Priority: Normal
Assignee:
Category:
Target version:This feature request stems from dealing with nested hashes, like the params from a request often dealt with in web frameworks.
Conditional code often needs to be written with multiple logical ANDs in order to achieve what this simple function can:
class Hash
def deep_value(*ks)
if ks.size
Updated by Eregon (Benoit Daloze) about 13 years ago
On 1 November 2011 01:26, SASADA Koichi ko1@atdot.net wrote:
(2011/11/01 8:52), Kyle Peyton wrote:
Example:
foo = {:bar => {:baz => 'blah'}}
foo.dv(:bar, :baz)
-> 'blah'
foo.dv(:cats)
-> nilJust idea.
How about to extend Hash#[] for it?--
// SASADA Koichi at atdot dot net
That would be nice.
Updated by alexeymuranov (Alexey Muranov) about 13 years ago
Konstantin Haase wrote:
Never mind, got it.
On Oct 31, 2011, at 17:32 , Haase, Konstantin wrote:
What's the difference (usability wise) between
hash[:foo][:bar]
and
hash.dv(:foo, :bar)
Konstantin
I'll answer anyway if someone else didn't get it :).
{ :foo => 1 }[2][3] raises NoMethodError, and { :foo => 1 }.dv(2,3) or { :foo => 1 }[2,3] should return nil.
Update: also it is possible to keep the list of all arguments in a single variable and call { :foo => 1 }.dv(*args)
Updated by alexeymuranov (Alexey Muranov) about 13 years ago
I can think of the following questions/objections to the suggested method definition:
- is
{ 1 => 2}.dv(1,1) # => nil
the desired result? - this method examines the (super)class name of an object, rather than the behavior of an object, so does not allow to mix nested hashes and arrays,
- this method calls itself recursively, while a loop would suffice.
The following is not a serious suggestion, but seriously, how about:
class Object
def deep_value(*keys)
obj = self
obj = obj[keys.shift] while !keys.empty? && obj.respond_to?(:[])
return obj
end
end
(For this to work well it will be important to call it #deep_value and not to redefine #[].)
Update. Another suggestion, probably a better one (at least simpler):
class Object
def deep_value(*keys)
obj = self
obj = obj[keys.shift] until keys.empty? || obj.nil?
return obj
end
end
Updated by nobu (Nobuyoshi Nakada) about 13 years ago
Updated by alexeymuranov (Alexey Muranov) about 13 years ago
Nobuyoshi Nakada wrote:
=begin
What about:class Hash
def
keys.inject(self) {|container, key| container.fetch(key) {return}}
end
end
=end
Just a small remark about defining this exclusively for Hash: what if some of the values is not a Hash but responds to #fetch? (will not look consistent enough to me).
Updated by trans (Thomas Sawyer) about 13 years ago
Probably best to use #[] internally too.
class Hash
def [](*keys)
keys.inject(self) {|container, key| value = container[key]; value ? value : return value}
end
end
@Alexey you may have a point. But I suspect it would need to be conditioned off of responding to #to_h or #to_hash instead of using is_a?(Hash)
.
Updated by neleai (Ondrej Bilka) about 13 years ago
Do you need hash or something like multidimensional hash class that uses [], each iterates on nested...
On Sun, Nov 06, 2011 at 05:48:52PM +0900, Thomas Sawyer wrote:
Issue #5531 has been updated by Thomas Sawyer.
Probably best to use #[] internally too.
class Hash def [](*keys) keys.inject(self) {|container, key| value = container[key]; value ? value : return value} end end
@Alexey you may have a point. But I suspect it would need to be conditioned off of responding to #to_h or #to_hash instead of using
is_a?(Hash)
.
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531Author: Kyle Peyton
Status: Open
Priority: Normal
Assignee:
Category:
Target version:This feature request stems from dealing with nested hashes, like the params from a request often dealt with in web frameworks.
Conditional code often needs to be written with multiple logical ANDs in order to achieve what this simple function can:
class Hash
def deep_value(*ks)
if ks.size == 1
return self[ks.shift]
else
val = ks.shift
return (self[val].is_a?(Hash) ? self[val].deep_value(*ks) : nil)
end
endalias dv deep_value
enddeep_value (dv) will simply recurse over a hash given a set of indexes and return the value at the end.
Example:
foo = {:bar => {:baz => 'blah'}}
foo.dv(:bar, :baz)
-> 'blah'
foo.dv(:cats)
-> nil
--
network packets travelling uphill (use a carrier pigeon)
Updated by mame (Yusuke Endoh) over 12 years ago
- Status changed from Open to Assigned
- Assignee set to matz (Yukihiro Matsumoto)
Updated by weexpectedTHIS (Kyle Peyton) over 12 years ago
What's the status of this issue? Good idea? Bad idea?
Updated by weexpectedTHIS (Kyle Peyton) over 12 years ago
I'd really like to see this in the next version of Ruby, it's a really common pattern.
Updated by weexpectedTHIS (Kyle Peyton) about 12 years ago
I think there is a strong case for this logic built in to ruby.
Updated by mame (Yusuke Endoh) almost 12 years ago
- Priority changed from Normal to 3
- Target version set to 2.6
matz expressed a negative opinion for similar proposal (in Japanese, #5550)
The original in Japanese:
Hashの本質はkey-valueのマッピングなので、valueが再帰的にHashであることを想定した(再帰的なHashでなければ役に立たない)メソッドを追加することには抵抗があります。
English translation:
The essence of Hash is a key-value mapping. I'm negative for adding a method that assumes that the value is a recursive hash, or a method that is useful only for a recursive hash.
--
Yusuke Endoh mame@tsg.ne.jp
Updated by dan.erikson (Dan Erikson) about 8 years ago
I believe this has recently been implemented as Hash#dig
.
Updated by shyouhei (Shyouhei Urabe) about 8 years ago
- Status changed from Assigned to Closed
Dan Erikson wrote:
I believe this has recently been implemented as
Hash#dig
.
Indeed. Closing peacefully.