Forum: Ruby-core [ruby-trunk - Feature #7292][Open] Enumerable#to_h

Posted by marcandre (Marc-Andre Lafortune) (Guest)
on 2012-11-06 18:54
(Received via mailing list)
Issue #7292 has been reported by marcandre (Marc-Andre Lafortune).

----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292

Author: marcandre (Marc-Andre Lafortune)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version:


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by nathan.f77 (Nathan Broadbent) (Guest)
on 2012-11-06 20:57
(Received via mailing list)
Issue #7292 has been updated by nathan.f77 (Nathan Broadbent).


I agree, Enumerable#to_h would make sense and be quite useful.

(1..3).to_h would be a special case for the Range class, because [1, 2, 
3].to_h should raise an exception.

Here's an example in Ruby:

module Enumerable
  def to_h
    hash = {}
    each_with_index do |el, i|
      raise TypeError, "(at index #{i}) Element is not an Array" unless 
Array === el
      raise IndexError, "(at index #{i}) Array has more than 2 elements" 
if el.size > 2
      hash[el[0]] = el[1]
    end
    hash
  end
end
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-32514

Author: marcandre (Marc-Andre Lafortune)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version:


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by matz (Yukihiro Matsumoto) (Guest)
on 2012-11-07 00:47
(Received via mailing list)
Issue #7292 has been updated by matz (Yukihiro Matsumoto).

Status changed from Open to Feedback
Priority changed from Normal to Low

So what's the difference from rejected #7241?
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-32523

Author: marcandre (Marc-Andre Lafortune)
Status: Feedback
Priority: Low
Assignee:
Category: core
Target version:


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by nathan.f77 (Nathan Broadbent) (Guest)
on 2012-11-07 02:07
(Received via mailing list)
Issue #7292 has been updated by nathan.f77 (Nathan Broadbent).


> So what's the difference from rejected #7241?

The main difference is that `to_h` wouldn't take a block or any 
arguments. It would be a simple conversion from Enumerable to Hash, and 
would only support a collection of arrays containing a maximum of 2 
elements.
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-32525

Author: marcandre (Marc-Andre Lafortune)
Status: Feedback
Priority: Low
Assignee:
Category: core
Target version:


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by mame (Yusuke Endoh) (Guest)
on 2012-11-07 04:32
(Received via mailing list)
Issue #7292 has been updated by mame (Yusuke Endoh).

Target version set to next minor


----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-32533

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by marcandre (Marc-Andre Lafortune) (Guest)
on 2012-11-07 04:49
(Received via mailing list)
Issue #7292 has been updated by marcandre (Marc-Andre Lafortune).


matz (Yukihiro Matsumoto) wrote:
> So what's the difference from rejected #7241?

As Nathan said, #7241 (and #666) accept a block and are therefore more 
related to the more complex categorize/associate/... #4151.

The implementation for `to_h` would be as simple conceptually as 
possible. It would be equivalent to:

module Enumerable
  def to_h
    result = {}
    each do |key, value|
      result[key] = value
    end
    result
  end
end

I believe this is the simplest definition one can think of. It doesn't 
try to do much, nor is it too strict (in the same way that "two".to_i 
returns 0).

mame (Yusuke Endoh) wrote:
> Use the traditional Hash[] in 2.0.0.

Indeed, Hash[] can be used instead, except it's really really ugly.

I can't think of any other global method we use like this that should be 
an instance method. It's very natural to transform data into a hashes, 
but instead of chaining the transformations we have to reverse the flow 
for this step. E.g. `source.map{...}.to_h.merge(...)` reads naturally, 
but `Hash[source.map{...}].merge(...)` doesn't.

The only other example of SomeClass.[] I can think of is for Set. In 
that case, it's understandable as Set doesn't have a dedicated creation 
syntax, so `Set[1, 2, 3]` has its charms. Are there other cases, besides 
Hash[]?

> I'm moving this ticket into the feature tracker.
Didn't I create it as a feature request?

----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-32535

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by mame (Yusuke Endoh) (Guest)
on 2012-11-07 05:01
(Received via mailing list)
Issue #7292 has been updated by mame (Yusuke Endoh).


marcandre (Marc-Andre Lafortune) wrote:
> > I'm moving this ticket into the feature tracker.
> Didn't I create it as a feature request?

Oops, I was mistaken.  I just set the target to next minor.  Sorry.

--
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-32536

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by prijutme4ty (Ilya Vorontsov) (Guest)
on 2012-11-07 19:02
(Received via mailing list)
Issue #7292 has been updated by prijutme4ty (Ilya Vorontsov).


Hash.[] is one of most disastrous ruby methods, IMHO. Since we don't 
have hash_map it's common to write smth like
hsh = Hash[ hsh.map{|k,v| [k.to_sym, v.to_f]} ]
In some more complicated cases it makes any programmer, who looks at 
code, cry.
Actually I'd prefer to have both methods Enumerable#to_h and 
Hash#hash_map ( http://bugs.ruby-lang.org/issues/6669 )
Programmers anyway use analogues for this method, so it'd be a way to 
standardize their code. As marcandre said #to_i also isn't ideal but is 
very useful and each programmer understand it the same way.
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-32576

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by marcandre (Marc-Andre Lafortune) (Guest)
on 2012-11-07 19:58
(Received via mailing list)
Issue #7292 has been updated by marcandre (Marc-Andre Lafortune).


> Actually I'd prefer to have both methods Enumerable#to_h and Hash#hash_map ( 
http://bugs.ruby-lang.org/issues/6669 )

I'm a strong supporter for different `hash_map/associate/categorize`, 
but let's not discuss these here please, they have their own tickets 
(#4151 & #6669).

This request is not meant to be a replacement for those requests. It is 
a small step, the simplest method to explicitly convert an Enumerable to 
a Hash.
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-32586

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by bitsweat (Jeremy Kemper) (Guest)
on 2012-11-07 22:32
(Received via mailing list)
Issue #7292 has been updated by bitsweat (Jeremy Kemper).


+1 to this.

I didn't like it at first because `#to_h` means coercion to me, and it 
doesn't make sense to coerce an Enumerable to a Hash. However, 
`Array#to_h` does seem like a good fit. Coerce this array of associated 
key/value pairs to a hash. Deal with edge cases in the same was as 
`Hash[]`.

I'd immediately change a lot of code to use this if it was available. 
Ending a chain of enumerable methods with `.to_h` is much nicer than 
"going back" to wrap it in `Hash[]`.

(Perhaps `Enumerable#to_h` could remain as a shortcut for `to_a.to_h`?)
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-32597

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by jipiboily (Jean-Philippe Boily) (Guest)
on 2013-03-01 13:54
(Received via mailing list)
Issue #7292 has been updated by jipiboily (Jean-Philippe Boily).


+1

This would just feel right and natural to me.
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-37221

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by newmen (Gleb Averchuk) (Guest)
on 2013-03-13 12:05
(Received via mailing list)
Issue #7292 has been updated by newmen (Gleb Averchuk).


I think this is very cool feature, because I'm tired of writing 
something like this:

some_hash = Hash[some_hash.map { |k, v| [k, (v * scale).to_i] }]

)=
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-37569

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by drbrain (Eric Hodel) (Guest)
on 2013-03-13 18:12
(Received via mailing list)
Issue #7292 has been updated by drbrain (Eric Hodel).


=begin
There is a potential for a security exploit with Enumerable#to_h:

  user_input = %w[rm -rf /]
  system ['ls', '-l'], *user_input

 With system, the first argument is used as the environment if it can be 
converted to a Hash. With user input to system this may lead to 
arbitrary code execution.
=end

----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-37576

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by marcandre (Marc-Andre Lafortune) (Guest)
on 2013-03-13 18:27
(Received via mailing list)
Issue #7292 has been updated by marcandre (Marc-Andre Lafortune).


drbrain (Eric Hodel) wrote:
> There is a potential for a security exploit with Enumerable#to_h:
>
>   user_input = %w[rm -rf /]
>   system ['ls', '-l'], *user_input
>
>  With system, the first argument is used as the environment if it can be 
converted to a Hash. With user input to system this may lead to arbitrary code 
execution.

I think you are confusing `to_h` (explicit conversion) with `to_hash` 
(implicit conversion). `system` calls rb_check_hash_type which will 
attempt to call `to_hash` but will *not* send `to_h` on its argument.

So no, there is no such potential security risk here.
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-37577

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
Posted by Roger Pack (rogerdpack)
on 2013-04-04 18:52
(Received via mailing list)
Issue #7292 has been updated by rogerdpack (Roger Pack).


+1 from me.  Sometimes after converting from an array to a hash I want 
to "convert back" to a hash and inevitably I reach for "to_h" just to 
discover it's not there.
----------------------------------------
Feature #7292: Enumerable#to_h
https://bugs.ruby-lang.org/issues/7292#change-38235

Author: marcandre (Marc-Andre Lafortune)
Status: Assigned
Priority: Low
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


Now that #to_h is the official method for explicit conversion to Hash, 
we should also add

  Enumerable#to_h: Returns a hash for the yielded key-value pairs.

    [[:name, 'Joe Smith'], [:age, 42]].to_h # => {name: 'Joe Smith', 
age: 42}


With the Ruby tradition of succint documentation I suggest the 
documentation talk about key-value pairs and there is no need to be 
explicit about the uninteresting cases like:

    (1..3).to_h           # => {1 => nil, 2 => nil, 3 => nil}
    [[1, 2], [1, 3]].to_h # => {1 => 3}
    [[1, 2], []].to_h     # => {1 => 2, nil => nil}

I see some reactions of people reading about the upcoming 2.0 release 
like this one:
http://globaldev.co.uk/2012/11/ruby-2-0-0-preview-...
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.