Bug #20064


Inconsistent behavior between array splat *nil and hash splat **nil

Added by zeke (Zeke Gabrielse) 6 months ago. Updated 5 months ago.

Target version:


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:

invitation = if params.key?(:inviter_id)
               { invitation_attributes: params.slice(:inviter_id) }

  email: 'john.doe@ruby.example',
  first_name: 'John',
  first_name: 'Doe',

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.

Updated by Dan0042 (Daniel DeLorme) 6 months ago

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

Updated by matz (Yukihiro Matsumoto) 6 months ago

The example in the proposal persuaded me. I accept allowing **nil. But I am against adding nil.to_h.


Updated by Dan0042 (Daniel DeLorme) 6 months ago

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, because many people are puzzled by the use of #to_hash.

Updated by jeremyevans0 (Jeremy Evans) 5 months ago

I submitted a pull request to support **nil:

Actions #5

Updated by jeremyevans (Jeremy Evans) 5 months ago

  • Status changed from Open to Closed

Applied in changeset git|5c823aa686a5549649df4af86d173bebed2418e1.

Support keyword splatting nil

nil is treated similarly to the empty hash in this case, passing
no keywords and not calling any conversion methods.

Fixes [Bug #20064]

Co-authored-by: Nobuyoshi Nakada


Also available in: Atom PDF