[ruby-core:115736] [Ruby master Bug#20064] Inconsistent behavior between array splat *nil and hash splat **nil

Issue #20064 has been reported by zeke (Zeke Gabrielse). ---------------------------------------- Bug #20064: Inconsistent behavior between array splat *nil and hash splat **nil https://bugs.ruby-lang.org/issues/20064 * Author: zeke (Zeke Gabrielse) * Status: Open * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- This has been discussed in #8507 and #9291 but both were closed because they lacked a clear use case. I think the following code should work, showing a clear use case: ```ruby invitation = if params.key?(:inviter_id) { invitation_attributes: params.slice(:inviter_id) } end User.create( email: 'john.doe@ruby.example', first_name: 'John', first_name: 'Doe', **invitation, ) ``` Per the previous discussions, this is because `*` uses explicit conversion to array (`to_a`, not `to_ary`), while `**` uses implicit conversion to hash (`to_hash`, not `to_h`). I find it confusing that you can splat nil into an array, but not nil into a hash. It would make sense for `**` to use explicit conversion. -- https://bugs.ruby-lang.org/

Issue #20064 has been updated by Dan0042 (Daniel DeLorme). I agree, for several years this topic just keeps popping up, being mentioned by many people as an odd situation. It's about time that something should be done about it. For the sake of backward compatibility I think that `**obj` should try #to_hash and then #to_h. Although in most cases they are the same if they both exist. On a related topic, `Hash(obj)` doesn't try #to_h and I think it should, similar to how `Array(obj)` tries both #to_ary and #to_a. I think this is a simple oversight; probably the behavior of `Hash()` should have been modified at the same time that `Array#to_h` and others were added in ruby 2.1 ---------------------------------------- Bug #20064: Inconsistent behavior between array splat *nil and hash splat **nil https://bugs.ruby-lang.org/issues/20064#change-105716 * Author: zeke (Zeke Gabrielse) * Status: Open * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- This has been discussed in #8507 and #9291 but both were closed because they lacked a clear use case. I think the following code should work, showing a clear use case: ```ruby invitation = if params.key?(:inviter_id) { invitation_attributes: params.slice(:inviter_id) } end User.create( email: 'john.doe@ruby.example', first_name: 'John', first_name: 'Doe', **invitation, ) ``` Per the previous discussions, this is because `*` uses explicit conversion to array (`to_a`, not `to_ary`), while `**` uses implicit conversion to hash (`to_hash`, not `to_h`). I find it confusing that you can splat nil into an array, but not nil into a hash. It would make sense for `**` to use explicit conversion. -- https://bugs.ruby-lang.org/

Issue #20064 has been updated by matz (Yukihiro Matsumoto). The example in the proposal persuaded me. I accept allowing `**nil`. But I am against adding `nil.to_h`. Matz. ---------------------------------------- Bug #20064: Inconsistent behavior between array splat *nil and hash splat **nil https://bugs.ruby-lang.org/issues/20064#change-105757 * Author: zeke (Zeke Gabrielse) * Status: Open * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- This has been discussed in #8507 and #9291 but both were closed because they lacked a clear use case. I think the following code should work, showing a clear use case: ```ruby invitation = if params.key?(:inviter_id) { invitation_attributes: params.slice(:inviter_id) } end User.create( email: 'john.doe@ruby.example', first_name: 'John', first_name: 'Doe', **invitation, ) ``` Per the previous discussions, this is because `*` uses explicit conversion to array (`to_a`, not `to_ary`), while `**` uses implicit conversion to hash (`to_hash`, not `to_h`). I find it confusing that you can splat nil into an array, but not nil into a hash. It would make sense for `**` to use explicit conversion. -- https://bugs.ruby-lang.org/

Issue #20064 has been updated by Dan0042 (Daniel DeLorme). matz (Yukihiro Matsumoto) wrote in #note-2:
But I am against adding `nil.to_h`.
`nil.to_h` already exists. Do you mean you are against using #to_h for double splats? If that's the case I would really appreciate if you could explain your reasoning. ---------------------------------------- Bug #20064: Inconsistent behavior between array splat *nil and hash splat **nil https://bugs.ruby-lang.org/issues/20064#change-105771 * Author: zeke (Zeke Gabrielse) * Status: Open * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- This has been discussed in #8507 and #9291 but both were closed because they lacked a clear use case. I think the following code should work, showing a clear use case: ```ruby invitation = if params.key?(:inviter_id) { invitation_attributes: params.slice(:inviter_id) } end User.create( email: 'john.doe@ruby.example', first_name: 'John', first_name: 'Doe', **invitation, ) ``` Per the previous discussions, this is because `*` uses explicit conversion to array (`to_a`, not `to_ary`), while `**` uses implicit conversion to hash (`to_hash`, not `to_h`). I find it confusing that you can splat nil into an array, but not nil into a hash. It would make sense for `**` to use explicit conversion. -- https://bugs.ruby-lang.org/

Issue #20064 has been updated by jeremyevans0 (Jeremy Evans). I submitted a pull request to support `**nil`: https://github.com/ruby/ruby/pull/9477 ---------------------------------------- Bug #20064: Inconsistent behavior between array splat *nil and hash splat **nil https://bugs.ruby-lang.org/issues/20064#change-106172 * Author: zeke (Zeke Gabrielse) * Status: Open * Priority: Normal * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- This has been discussed in #8507 and #9291 but both were closed because they lacked a clear use case. I think the following code should work, showing a clear use case: ```ruby invitation = if params.key?(:inviter_id) { invitation_attributes: params.slice(:inviter_id) } end User.create( email: 'john.doe@ruby.example', first_name: 'John', first_name: 'Doe', **invitation, ) ``` Per the previous discussions, this is because `*` uses explicit conversion to array (`to_a`, not `to_ary`), while `**` uses implicit conversion to hash (`to_hash`, not `to_h`). I find it confusing that you can splat nil into an array, but not nil into a hash. It would make sense for `**` to use explicit conversion. -- https://bugs.ruby-lang.org/
participants (4)
-
Dan0042 (Daniel DeLorme)
-
jeremyevans0 (Jeremy Evans)
-
matz (Yukihiro Matsumoto)
-
zeke (Zeke Gabrielse)