Feature #20498
openNegated method calls
Description
I want to propose the following syntax: foo.!bar
. I know it's already valid syntax, but please read on for details.
When someone write a somewhat long line of code that is negated, the main way I've seen of doing it is:
must_create_user = !User.where(somelong: :condition, even_more: "thing").exists?
I personally highly dislike it, as I must keep the "not" in the back of my mind as I read the line. When quickly reading a line like this, it's super easy to misread and understand the opposite result.
The current ways around this I can think of are:
- rename the variable (can be annoying)
- Use
unless
(only possible when in a condition; some people, like me, have a hard time grapsping aunless
) - use a
.!
in the end (foo.exists?.!
), I've never seen that and it looks ugly to me (this is subjective). - create a new method name with the negated meaning (not always possible)
My proposal would look like this:
must_create_user = User.where(somelong: :condition, even_more: "thing").!exists?
You cannot forget the bang that you saw 15 words ago, it's right there.
It also basically reads as English: "user where ... doesn't exists".
The main argument against this I can think of is that it's technically already a valid syntax. I believe it's frowned upon to override the bang operator and I'm not aware of places where it is overridden to with also having a parameter.
I made a prototype in RubyNext, which you can try here: https://ruby-next.github.io/#gist:0e133bf6f27f2437193dc034d58083dc
Clarification: the prototype is not perfect and does not handle foo&.!empty?
. In that case, if foo
is nil
, the result of the expression would be nil
.