Ruby: Logical Operators

Although 'if' expressions are extremely useful and can provide excellent flow control, sometimes more complex conditions are necessary for the level of control and logic that a program requires. There are some messy ways to get around this by playing with variables and different things, or you could simply nest a lot of 'if's and maybe repeat some code to achieve your goal, but to trump all of these for most use cases, you could make use of some things called logical operators.

Logical operators, sometimes called boolean operators, evaluate expressions (or a singular expression in the case of some) and then change what the boolean evaluation is. There are three main logical operators in Ruby:

  • and
  • or
  • not

Let's go through them.

and

The "and" operator in Ruby takes two expressions and returns "true" if both are true, and "false" if one or more of them is false. It operates much like the word "and" does in a simple English sentence -- you might say "If 1+1 is 2 AND 2+3 is 5, then do something", and this can be represented in Ruby using this "and" logical operator, represented by simply using the and keyword.

In the previous tutorial about 'if', we wrote a simple program which takes a username and password, and then does some authentication by using some nested 'if' statements. An easier (and arguably "better") way to do this would be to utilise the and logical operator with something like the following:

1
2
3
if username == "foo" and password == "bar"
	puts "Welcome, administrator!"
end

Much cleaner! Remember that all of these logical operators can be used with any boolean values – any conditions that you formulate using conditional operators, or if you're doing something a bit more complex, values returned from methods or other fancy thing.

or

As you'd expect, the "or" operator in Ruby functions much like the "and" operator. It takes two expressions and then checks if one or the other is true – once again this is much like you'd find in a regular sentence with something like "If the user's name is Joe OR he has the special access code". Similarly to "and", "or" is represented in Ruby by the or keyword – so once again using our username and password example, if we wanted the user to have the correct username or the correct password and let them in, we could write something like the following:

1
2
3
if username == "foo" or password == "bar"
	puts "Welcome, administrator!"
end

The only real alternative to using the "or" operator at this point would be to have two separate if-statements, one which checks the username and one which checks the password, and then repeating in each what we want to do when one or the other is true. This is extremely messy and breaks the fundamental DRY (Don't Repeat Yourself) "rule" of object orientated programming -- using or is much better.

not

The last logical operator we're going to talk about in this tutorial is a little bit different than the others. The "not" operator gets an expression and inverts its boolean value – so given a true condition it will return false. This, once again functions as linguistics would suggest, for example "If the username is not foo". The "not" operator is represented in Ruby by the not keyword, and as such we could create functionality equal to if username != "foo" using if not(username == "foo").

The obvious thought process from here is to ask why it is useful if we can just use != instead. Well in this case, I admit it isn't incredibly useful. not begins to become more useful when you have longer and more complex conditions that you want to invert, or if you want to invert the boolean value returned from a method. An example of inverting a more complex condition might be something like the following:

1
2
3
if not(username == "foo" and password == "bar")
	puts "Hey! You aren't allowed in here, get out!"
end

Once again I've demonstrated a purpose of not which doesn't make it seem entirely useful as this could be accomplished very easily via other means (!= is another alternative in this case) – however the not above does make the logic of the code easier to read, and trust me when I say that not is an extremely useful logical operator in some cases.