Bug #20064
closedInconsistent behavior between array splat *nil and hash splat **nil
Description
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) }
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.
Updated by Dan0042 (Daniel DeLorme) 11 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) 11 months ago
The example in the proposal persuaded me. I accept allowing **nil
. But I am against adding nil.to_h
.
Matz.
Updated by Dan0042 (Daniel DeLorme) 11 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) 10 months ago
I submitted a pull request to support **nil
: https://github.com/ruby/ruby/pull/9477
Updated by jeremyevans (Jeremy Evans) 10 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 nobu@ruby-lang.org