Crystal: Add `Object#not_nil?` method

Created on 24 Aug 2018  路  8Comments  路  Source: crystal-lang/crystal

My usecase:

  • Null means explicit ?email=null in HTTP request query, nil is when there is no email in the query at all
  • params is a strict NamedTuple
  • params[:min_wage] is UInt16 | Nil, params[:available] is Bool | Nil, other params are String | Null | Nil
{% for attr in %w(name email about available min_wage) %}
  case params[{{attr}}]
  when Null      then user.{{attr.id}} = nil
  when .not_nil? then user.{{attr.id}} = params[{{attr}}].not_nil!
  end
{% end %}

I won't write this:

case params[{{attr.id}}]
when Null   then user.{{attr.id}} = nil
when String, UInt16, Bool then user.{{attr.id}} = params[{{attr}}]
end

Because

  1. Those types are defined somewhere else and I don't want to duplicate them in the macro.
  2. There may be many types which would lead to a big when clause.

The code to add is pretty simple:

abstract class Object
  def not_nil?
    !nil?
  end
end

I hope it's enough words for such a small feature request, thanks!

Most helpful comment

One thing to know is that changing the your code is 1000x times simpler than changing the language syntax or standard library. If it means adding one more line, or just a few more lines, to your code, but you can do it, then there's absolutely no way we are going to make a change on our side.

I recommend watching "Simple made easy". Of course it's easier to write it the way you want, but it's less simple because it adds yet anoteh redundant method to the standard library.

Finally, Crystal is open. You can add that method to your code if you really want to.

All 8 comments

You can use

  case params[{{attr}}]
  when Null      then user.{{attr.id}} = nil
  when .nil?
  else user.{{attr.id}} = params[{{attr}}].not_nil!
  end

I prefer the use of when String, UInt16, Bool then user.{{attr.id}} = params[{{attr}}]. If you can avoid the use of .not_nil!, do.

@j8r 5 loc vs 4 loc, no ugly empty line, consistent indentation; .not_nil? wins.

I prefer the use of when String, UInt16, Bool then user.{{attr.id}} = params[{{attr}}]

I've clearly stated two reasons why I won't use it.

Just use if and elsif with !params[{{attr}}].nil? condition.

@straight-shoota of course I could do that either. However, compare this:

{% for attr in %w(name email about available min_wage) %}
  if params[{{attr}}].is_a?(Null)
    user.{{attr.id}} = nil
  elsif !params[{{attr}}].nil?
    user.{{attr.id}} = params[{{attr}}].not_nil!
  end
{% end %}

To this:

{% for attr in %w(name email about available min_wage) %}
  case params[{{attr}}]
  when Null      then user.{{attr.id}} = nil
  when .not_nil? then user.{{attr.id}} = params[{{attr}}].not_nil!
  end
{% end %}

The second approach is much more readable.

That depends on who you ask. I don't think there is much difference between both examples and they're very similar in terms of readability. You don't need .not_nil! btw. with .nil?.

And you also shouldn't need it for .not_nil? which in turn means it is more complicated to implement. Without a real benefit.

One thing to know is that changing the your code is 1000x times simpler than changing the language syntax or standard library. If it means adding one more line, or just a few more lines, to your code, but you can do it, then there's absolutely no way we are going to make a change on our side.

I recommend watching "Simple made easy". Of course it's easier to write it the way you want, but it's less simple because it adds yet anoteh redundant method to the standard library.

Finally, Crystal is open. You can add that method to your code if you really want to.

You can add that method to your code if you really want to.

But it won't apply implicit type restrictions like .nil? does.
Without that, it really doesn't make any sense. But adding that would be even much more complicated than the "pretty simple" example in the OP.

The code works in my project, so I proposed it to the standard library. Thanks @straight-shoota and @asterite for thorough explanations on why you wouldn't want to apply it. Arguments lead to the truth (more than thumbs down).

Was this page helpful?
0 / 5 - 0 ratings