[ruby-core:109694] [Ruby master Feature#18959] Handle gracefully nil kwargs eg. **nil
From:
"austin (Austin Ziegler)" <noreply@...>
Date:
2022-08-25 15:13:52 UTC
List:
ruby-core #109694
Issue #18959 has been updated by austin (Austin Ziegler).
LevLukomskyi (Lev Lukomskyi) wrote in #note-10:
> ```ruby
> res = {
> some: 'value',
> }
> res.merge!(id: id, name: name) if id.present?
> res
> ```
>
> vs
>
> ```ruby
> {
> some: 'value',
> **({ id: id, name: name } if id.present?),
> }
> ```
>
> The second option looks more concise to me.
I do not find the second option clearer or more concise in any way. It feels much more of line-noise.
In my code, I would opt for an explicit function that does the logic required *for* me, rather than trying to do it in-line, and it would probably be something like this:
```ruby
def default_options
{
id: :omit,
name: :omit
}
end
def resolve_options(*overrides)
default_options.merge(*overrides.compact!) { |k, default, value|
value.nil? : default : value
}.delete_if { |k, v| v == :omit }
end
# later, at the call-site
some_function(resolve_options(some: 'value', id: id, name: name))
# or
some_function(resolve_options({some: 'value'}, {id: id, name: name} if id.present?))
```
My nose twitches at complex inline if statements as you demonstrated.
It could be nice if `**nil` resulted in `{}`, but it has a high probability for compatibility issues, so I think caution is warranted.
----------------------------------------
Feature #18959: Handle gracefully nil kwargs eg. **nil
https://bugs.ruby-lang.org/issues/18959#change-98920
* 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: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>