unless
If postfix conditionals weren't controversial enough, Ruby also offers the unless keyword to really grind the gears of orthodox programmers.
But after all, being an able reader of English prose, you already know what unless means, so why wouldn't we use it when programming?
puts "Hello, world!" unless greeting_disabled?
if (!greetingDisabled()) console.log("Hello, world!");
What we're getting at here is straightforward enough: exclamation points for negating booleans are "computer language" and here in Ruby land we prefer human language.
Trouble in paradise
As we gain experience in Ruby, odds are that we will converge on the same realization: unless is more confusing to read than if for non-trivial cases. Here's the cheat sheet for idiomatic usage:
# Excellent: simple postfix condition
puts "Hello, world!" unless greeting_disabled?
# Good: simple infix condition
unless user.admin?
puts "You don't have permission to do this."
end
# Okay: multiple conditions
unless user.reader? && user.writer?
puts "You don't have permission to do this."
end
# Uncomfortable: mixing || and &&
unless (user.reader? && user.writer?) || user.admin?
puts "Unauthorized!"
end
# Bad: conditionals which may as well be if statements
unless user.nil?
puts "Welcome, #{user.name}!"
end
# (more simply expressed as "if user ..." instead)
# Very bad: negated conditions
unless !user.admin?
puts "Welcome, admin!"
end
# Your mind will break: mixed negated and non-negated conditions
unless user.reader? && !user.admin?
puts "Welcome, admin!"
end
So please enjoy using unless, but remember to do so responsibly!
History
unless has been part of Ruby since its inception. The inspiration must have come from Perl, the only pre-Ruby language with this concept.
Post-Ruby, languages with unless include Crystal, Elixir and CoffeeScript (may you rest in peace 💐).