From: "austin (Austin Ziegler)" Date: 2022-08-27T00:21:14+00:00 Subject: [ruby-core:109724] [Ruby master Feature#18959] Handle gracefully nil kwargs eg. **nil Issue #18959 has been updated by austin (Austin Ziegler). LevLukomskyi (Lev Lukomskyi) wrote in #note-19: > > Both @sawa and I have provided better options than your examples. > > It looks like you guys are ashamed of `**` and try to avoid it at all costs, instead of grasping this new language feature. Not at all. I���ve used `**` for a *very* long time (since kwargs were introduced). But I also tend to do `**(options || {})` and I don���t write hard-to-read code like `**({id: id, name: name} if id.present?)`. > Also, I've found one more [good example](https://www.semicolonandsons.com/code_diary/ruby/double-splat-cannot-handle-nil). Here a programmer has to write this: > ```ruby > def add_email_to_list(email:, tracking_info:) > EmailSubscriber.find_by(email: email) || EmailSubscriber.new( > email: email, **(tracking_info || {}) > ) > ... > end > ``` > instead of just writing this: > ```ruby > def add_email_to_list(email:, tracking_info:) > EmailSubscriber.find_by(email: email) || EmailSubscriber.new( > email: email, **tracking_info > ) > ... > end > ``` I���d write that as: ```ruby def add_email_to_list(email:, tracking_info: {}) EmailSubscriber.find_by(email: email) || EmailSubscriber.new(email: email, **tracking_info) end ``` It *is* a different signature (`tracking_info` is no longer a required kwarg) but it���s a *better* API and doesn���t require any special shenanigans. I���m not arguing against the improvement of `**` or even permitting `**nil`. But the example you���ve given is completely unconvincing because it is suboptimal, has unnecessary allocations, and is more reminiscent of what I���d see from Perl in 1998 than Ruby of 2022. I think that there are two things that could help: 1. If we want to allow `**nil`, the argument should be made to switch `**` from calling `#to_hash` to calling `#to_h`, because that would give you `**nil` _for free_. That would require digging a bit deeper to determine why `**` calls `#to_hash` instead of `#to_h`. 2. `Hash#merge` and `Hash#update` could be modified to ignore `nil` arguments (which would permit your use-case). ---------------------------------------- Feature #18959: Handle gracefully nil kwargs eg. **nil https://bugs.ruby-lang.org/issues/18959#change-98959 * Author: LevLukomskyi (Lev Lukomskyi) * Status: Open * Priority: Normal ---------------------------------------- The issue: ```ruby def qwe(a: 1) end qwe(**nil) #=> fails with `no implicit conversion of nil into Hash (TypeError)` error { a:1, **nil } #=> fails with `no implicit conversion of nil into Hash (TypeError)` error ``` Reasoning: I found myself that I often want to insert a key/value to hash if a certain condition is met, and it's very convenient to do this inside hash syntax, eg.: ```ruby { some: 'value', **({ id: id } if id.present?), } ``` Such syntax is much more readable than: ```ruby h = { some: 'value' } h[:id] = id if id.present? h ``` Yes, it's possible to write like this: ```ruby { some: 'value', **(id.present? ? { id: id } : {}), } ``` but it adds unnecessary boilerplate noise. I enjoy writing something like this in ruby on rails: ```ruby content_tag :div, class: [*('is-hero' if hero), *('is-search-page' if search_page)].presence ``` If no conditions are met then the array is empty, then converted to nil by `presence`, and `class` attribute is not rendered if it's nil. It's short and so convenient! There should be a similar way for hashes! I found this issue here: https://bugs.ruby-lang.org/issues/8507 where "consistency" thing is discussed. While consistency is the right thing to do, I think the main point here is to have fun with programming, and being able to write stuff in a concise and readable way. Please, add this small feature to the language, that'd be so wonderful! ���� -- https://bugs.ruby-lang.org/ Unsubscribe: