Project

General

Profile

Feature #9239

Array#to_h ignores flat arrays

Added by Tsuyoshi Sawada about 2 years ago. Updated about 2 years ago.

Status:
Rejected
Priority:
Normal
Assignee:
[ruby-core:59032]

Description

=begin
My understanding was that the newly introduced Array#to_h was to be equivalent to Hash.[]. But when I give a flat array, it returns an empty hash:

[:a, :b].to_h # => {}
[:a].to_h     # => {}

I expected {:a => :b} for the first example, and ArgumentError: odd number of arguments for Hash for the second example, as is with Hash[]. Was it intended to be different? If so, why is that the case? Even if it is to be different, it should at least raise an error when a flat array is given.
=end


Related issues

Related to Backport21 - Backport #9270: Array#to_h should not ignore badly formed elements Closed 12/21/2013

Associated revisions

Revision 44354
Added by Marc-Andre Lafortune about 2 years ago

  • array.c: Have to_h raise on elements that are not key-value pairs [#9239]

  • enum.c: ditto

Revision 44354
Added by Marc-Andre Lafortune about 2 years ago

  • array.c: Have to_h raise on elements that are not key-value pairs [#9239]

  • enum.c: ditto

History

#1 Updated by Marc-Andre Lafortune about 2 years ago

  • Tracker changed from Bug to Feature

#2 [ruby-core:59033] Updated by Marc-Andre Lafortune about 2 years ago

  • Assignee set to Yukihiro Matsumoto

Moving to "feature", as the current documentation states that elements that are not 2-element arrays are ignored, so it is different from Hash.[]

My opinion is that the fact that Hash[1,2,3,4] # => {1 => 2, 3 => 4} is a misfeature and that this usage should not be encouraged.

On the other hand, Array#to_h could raise an error on elements that are not 2-element arrays. I argued otherwise before, but maybe that would be safer.

#3 [ruby-core:59034] Updated by Alexey Muranov about 2 years ago

If [:a, :b].to_h returned {:a => :b}, then what should [[:a, :b], [:c, :d]].to_h return? {[:a, :b] => [:c, :d]} ?

#4 [ruby-core:59038] Updated by Tsuyoshi Sawada about 2 years ago

marcandre (Marc-Andre Lafortune) wrote:

My opinion is that the fact that Hash[1,2,3,4] # => {1 => 2, 3 => 4} is a misfeature and that this usage should not be encouraged.

On the other hand, Array#to_h could raise an error on elements that are not 2-element arrays. I argued otherwise before, but maybe that would be safer.

I agree.

#5 [ruby-core:59114] Updated by Marc-Andre Lafortune about 2 years ago

One reason I think I was wrong is that current form could encourage code like:

enum.map{|x| [x.foo, x.bar] if x.baz? }.to_h

using the fact that any nil will be ignored. I'm not sure that it's a good idea.

It would probably be safer to raise an Exception for elements that are not a key-value pair. It also satisfies fail-early principle.

Matz, what do you think?

#6 [ruby-core:59162] Updated by Marc-Andre Lafortune about 2 years ago

  • Category set to core
  • Assignee changed from Yukihiro Matsumoto to Marc-Andre Lafortune
  • Target version set to 2.1.0

I got the green light from Matz, thanks :-)

Naruse-san: could you please confirm that there is no problem on your end for me to commit the following patch: https://github.com/marcandre/ruby/compare/to_h_raise

Thanks

#7 [ruby-core:59165] Updated by Zachary Scott about 2 years ago

I dont think we should commit this before 2.1, is there good reason?

#8 [ruby-core:59170] Updated by Marc-Andre Lafortune about 2 years ago

Since this is a new feature, there's no risk of regression and there is no incompatibility. Committing after 2.1 could create incompatibility.

#9 [ruby-core:59173] Updated by Zachary Scott about 2 years ago

How would committing after 2.1 create incompatibility?

If we commit this feature to trunk after ruby_2_1 branch is created, then it won't be released until 2.2, right?

#10 [ruby-core:59175] Updated by Marc-Andre Lafortune about 2 years ago

zzak (Zachary Scott) wrote:

How would committing after 2.1 create incompatibility?

If some rubyists write code for Ruby 2.1 using this new Arry#to_h and rely on the fact that elements that are not key value pairs are ignored, then this change in 2.2 will break their code. This is what I mean by incompatibility.

#11 [ruby-core:59183] Updated by Zachary Scott about 2 years ago

I think you should ask for permission from naruse before you commit

#12 [ruby-core:59188] Updated by Tsuyoshi Sawada about 2 years ago

marcandre (Marc-Andre Lafortune),

Thanks for the patch to reflect my request, and thanks for ALREADY HAVING ASKED Naruse-san for the commit.

#13 [ruby-core:59199] Updated by Marc-Andre Lafortune about 2 years ago

  • Assignee changed from Marc-Andre Lafortune to Yui NARUSE
  • Priority changed from Normal to 6

#14 [ruby-core:59232] Updated by Yui NARUSE about 2 years ago

  • Status changed from Open to Rejected

As Array#to_h says and test_to_h describes, Array#to_h is different from Hash[].
The behavior is expected one.

Returns the result of interpreting ary as an array of
[key, value] pairs. Elements other than pairs of
values are ignored.

#15 [ruby-core:59236] Updated by Marc-Andre Lafortune about 2 years ago

Yui, I'm wondering if you actually read the whole thread. In any case, I probably don't have to point out that Matz usually has the privilege of rejecting feature requests.

I've summarized it as #9270.

Also available in: Atom PDF