Reputation: 1150
I'm upgrading an app from Ruby 1.9.3 to 2.0.0 and I've come across the following:
1.9.3-p545 :001 > Hash[[[], 0]]
# => {}
vs.
2.0.0-p643 :001 > Hash[[[], 0]]
# ArgumentError: invalid number of elements (0 for 1..2)
# :1:in `[]'
I have not been able to find an explanation in the docs or the changelog but I feel like it should be obvious. Can someone explain what changed?
Upvotes: 1
Views: 233
Reputation: 37627
I couldn't find any documentation either, but it seems clear that Ruby changed from quietly discarding bad data in 1.9 to raising an error about it in 2.0.
The relevant part of the documentation didn't change from 1.9 to 2.0: if Hash[]
gets a single argument which is an array, that array is expected to be an array of [key, value]
pairs, and is converted to a Hash
accordingly. (In 1.9 Hash[]
was the only way to do that conversion; in 2.0 you can call .to_h
on an array.)
The first element in [[], 0]
isn't a [key, value]
pair, and neither is the second element.
Ruby 1.9 quietly discards both elements, resulting in an empty hash. Ruby 1.9 does convert the valid elements in an array with both valid and invalid elements:
Hash[[[], [:a, :b], 0]]] == {:a=>:b}
Instead of quietly discarding the invalid elements, Ruby 2 (both 2.0.0 and the recent releases of 2.1 and 2.2 I have handy) reports the first invalid element with the ArgumentError
you cite.
Interestingly, the ArgumentError
tips us off to an otherwise undocumented feature: in both 1.9 and 2.*, Hash[]
converts one-element arrays in a single array argument to hash keys whose value is nil
. And you can intermix one- and two-element arrays. This feature must be for backward compatibility, because 2.*'s Array#to_h
only accepts two-element arrays.
Upvotes: 1