ruby-style-guide icon indicating copy to clipboard operation
ruby-style-guide copied to clipboard

Do not use unless with multiple conditions

Open ProZsolt opened this issue 8 years ago • 6 comments

ProZsolt avatar Jan 30 '17 12:01 ProZsolt

Your example encourages developers to attempt to perform Boolean algebra on potentially long conditionals. Remembering to toggle the ! on each condition, as well as to toggle between && and || usages throughout the condition chain is a rather taxing mental task.

# bad
unless definitely_bad? || !good? && good_for_nothing?
  do_something
end

# good?
if !definitely_bad? && good? || !good_for_nothing? # I don't even know if this all evaluates the same
  do_something
end

What do you think of changing the good example to if !(conditions)?

# bad
unless definitely_bad? || !good? && good_for_nothing?
  do_something
end

# good
if !(definitely_bad? || !good? && good_for_nothing?)
  do_something
end

thepeoplesbourgeois avatar May 26 '17 19:05 thepeoplesbourgeois

I wonder why this hasn't been discussed more since it was proposed, let alone why it has not been accepted. I too find it very odd to read complex unless conditions.

gnapse avatar Mar 12 '18 22:03 gnapse

Remembering to toggle the ! on each condition, as well as to toggle between && and || usages throughout the condition chain is a rather taxing mental task.

I'd rather have the author of the code do this once, than having the readers of the code having to decode such a complex boolean expression every time they read the code.

And remember that the author of the code is also a future reader of it.

gnapse avatar Mar 12 '18 23:03 gnapse

Instead of the boolean algebra, the other solution to "unless with multiple conditions" is extracting the conditions to a method.

mikegee avatar Mar 13 '18 20:03 mikegee

Yes, that would be a solution too. Anything that avoids a final result where you have something like

unless something || somethingElse

That's up to the author of the code to refactor their code when it is flagged as violating this proposed rule.

gnapse avatar Mar 13 '18 22:03 gnapse

Consider this case:

unless admin? || superuser?
  return "You are not authorized"
end

That feels much more natural to me than

if !admin? && !superuser?
  return "You are not authorized"
end

In English wouldn't you explain the requirements as "they must be either an admin or a super user to perform this action" rather than "they are not allowed to perform this action if they are not an admin and not a super user"?

jonathonjones avatar Apr 05 '18 22:04 jonathonjones