Forum: Ruby-core [ruby-trunk - Feature #5531][Open] deep_value for dealing with nested hashes

Posted by Kyle Peyton (weexpectedthis)
on 2011-11-01 00:53
(Received via mailing list)
Issue #5531 has been reported by Kyle Peyton.

----------------------------------------
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531

Author: 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
  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
Posted by SASADA Koichi (Guest)
on 2011-11-01 01:27
(Received via mailing list)
(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?
Posted by Haase, Konstantin (Guest)
on 2011-11-01 01:33
(Received via mailing list)
What's the difference (usability wise) between

  hash[:foo][:bar]

and

  hash.dv(:foo, :bar)

Konstantin
Posted by Haase, Konstantin (Guest)
on 2011-11-01 01:33
(Received via mailing list)
What's the difference (usability wise) between

  hash[:foo][:bar]

and

  hash.dv(:foo, :bar)

Konstantin
Posted by Haase, Konstantin (Guest)
on 2011-11-01 01:34
(Received via mailing list)
Never mind, got it.
Posted by Benoit Daloze (Guest)
on 2011-11-01 12:12
(Received via mailing list)
On 1 November 2011 01:26, SASADA Koichi <ko1@atdot.net> wrote:
> How about to extend Hash#[] for it?
>
> --
> // SASADA Koichi at atdot dot net

That would be nice.
Posted by Alexey Muranov (alexey_m)
on 2011-11-01 12:35
(Received via mailing list)
Issue #5531 has been updated by Alexey Muranov.


Konstantin Haase wrote:
>  >   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 }.[2,3] should 
return nil.
----------------------------------------
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531

Author: 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
  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
Posted by Alexey Muranov (alexey_m)
on 2011-11-01 13:45
(Received via mailing list)
Issue #5531 has been updated by Alexey Muranov.


I can think of the following questions/objections to the suggested 
method definition:
1. is `{ 1 => 2}.dv(1,1) # => nil` the desired result?
2. 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,
3. 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 #[].)
----------------------------------------
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531

Author: 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
  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
Posted by Nobuyoshi Nakada (nobu)
on 2011-11-01 14:34
(Received via mailing list)
Issue #5531 has been updated by Nobuyoshi Nakada.


=begin
What about:

  class Hash
    def [](*keys)
      keys.inject(self) {|container, key| container.fetch(key) {return}}
    end
  end
=end

----------------------------------------
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531

Author: 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
  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
Posted by Alexey Muranov (alexey_m)
on 2011-11-01 14:43
(Received via mailing list)
Issue #5531 has been updated by Alexey Muranov.


Nobuyoshi Nakada wrote:
> =begin
> What about:
>
>   class Hash
>     def [](*keys)
>       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 to me).

----------------------------------------
Feature #5531: deep_value for dealing with nested hashes
http://redmine.ruby-lang.org/issues/5531

Author: 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
  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
Posted by Thomas Sawyer (7rans)
on 2011-11-06 09:49
(Received via mailing list)
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/5531

Author: 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
  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
Posted by "Ondřej Bílka" <neleai@seznam.cz> (Guest)
on 2011-11-06 17:00
(Received via mailing list)
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:
>     end
> Assignee:
>     if ks.size == 1
>
>
>
> --
> http://redmine.ruby-lang.org

--

network packets travelling uphill (use a carrier pigeon)
Posted by mame (Yusuke Endoh) (Guest)
on 2012-03-27 15:51
(Received via mailing list)
Issue #5531 has been updated by mame (Yusuke Endoh).

Status changed from Open to Assigned
Assignee set to matz (Yukihiro Matsumoto)


----------------------------------------
Feature #5531: deep_value for dealing with nested hashes
https://bugs.ruby-lang.org/issues/5531#change-25243

Author: weexpectedTHIS (Kyle Peyton)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
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
  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
Posted by Kyle Peyton (weexpectedthis)
on 2012-03-29 18:05
(Received via mailing list)
Issue #5531 has been updated by weexpectedTHIS (Kyle Peyton).


What's the status of this issue?  Good idea?  Bad idea?
----------------------------------------
Feature #5531: deep_value for dealing with nested hashes
https://bugs.ruby-lang.org/issues/5531#change-25390

Author: weexpectedTHIS (Kyle Peyton)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
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
  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
Posted by Kyle Peyton (weexpectedthis)
on 2012-06-26 20:11
(Received via mailing list)
Issue #5531 has been updated by weexpectedTHIS (Kyle Peyton).


I'd really like to see this in the next version of Ruby, it's a really 
common pattern.
----------------------------------------
Feature #5531: deep_value for dealing with nested hashes
https://bugs.ruby-lang.org/issues/5531#change-27491

Author: weexpectedTHIS (Kyle Peyton)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
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
  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
Posted by Kyle Peyton (weexpectedthis)
on 2012-10-02 00:12
(Received via mailing list)
Issue #5531 has been updated by weexpectedTHIS (Kyle Peyton).


I think there is a strong case for this logic built in to ruby.
----------------------------------------
Feature #5531: deep_value for dealing with nested hashes
https://bugs.ruby-lang.org/issues/5531#change-29926

Author: weexpectedTHIS (Kyle Peyton)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
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
  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
Posted by mame (Yusuke Endoh) (Guest)
on 2012-11-24 00:45
(Received via mailing list)
Issue #5531 has been updated by mame (Yusuke Endoh).

Priority changed from Normal to Low
Target version set to next minor

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>
----------------------------------------
Feature #5531: deep_value for dealing with nested hashes
https://bugs.ruby-lang.org/issues/5531#change-33673

Author: weexpectedTHIS (Kyle Peyton)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category:
Target version: next minor


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
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.