Lua: Logical Operators

In the previous tutorial we learnt about 'if' statements and how we can execute certain pieces of code if a certain condition is true. In this tutorial we're going to expand on this and learn about three different things called logical operators, which can help enhance and empower the functionality we learnt about in the previous tutorial.

The first logical operator we're going to learn about is the 'and' logical operator. This operator is usually used to mash two conditions together - if one condition is true and another condition is true, then do something. You can probably already see how this would be helpful in creating 'if' statements with more complex conditions.

In Lua, the "and" logical operator is expressed by simply writing the and keyword between two conditions - so if we wanted to create an application which requires two conditions for it to execute a certain portion of code, we might write something like the following:

1
2
3
if variable_number > 9000 and variable_number < 10000 then --If it's over 9000 _and_ less than 10000
	print("Key '" .. variable_number .. "' is correct")
end --It might be a nice idea to put an 'else' here

The above code would work correctly if "variable_number" was a variable which existed, and the code inside the 'if' statement would execute if the variable contained a number over 9000 but less than 10000. An issue, however, would arise if input from the user was put into "variable_number" and then it was put through this comparison - the issue being that the input from the user will be in the form of a string, and Lua doesn't automatically convert strings in conditions to numbers (for a good reason, it could cause all kinds of problems), this unfortunately means that the conditions will always be false.

Luckily for us, Lua has a nice function which converts strings to numbers called tonumber - it will return, what we call it when a function gives a value back to us, the number that the string is converted to if the string has been converted successfully, and it will return nil, the data type in Lua for expressing the concept of 0 or 'nothing', if the string could not be converted. As such, we can use this on a string received from the user to convert it into a number value, and display an error message if the conversion was not successful, with something like the following:

1
2
3
4
5
6
7
8
9
10
11
12
io.write("Enter an ID number: ")
identification_number = tonumber(io.read())

if identification_number == nil then
	print("Invalid ID number.")
else
	if identification_number > 9000 and identification_number < 10000 then --If it's over 9000 and less than 10000
		print("Key, '" .. identification_number .. "', is valid.")
	else
		print("Access denied.")
	end
end

Notice that I wrapped the whole of the if statement we previously formulated in an 'else' section so it will be executed if the ID is a valid number. Statements can be nested like this without problems in Lua (which is awesome!). Also note that elseifs could be used here, but in this case it makes more sense to me to have separate 'if' blocks.

The next logical operator we're going to talk about is the 'or' operator. It functions much like the 'and' operator that we just talked about, however checks if one condition or another is true rather than if both are true (and if both are true, it will also be true). It's used exactly like the 'and' operator, and so without much explanation, some code which utilises the or logical operator is as follows:

1
2
3
4
5
6
7
8
io.write("Enter your username: ")
username = io.read()

if username == "joe" or username=="admin" then
	print("Access granted.")
else
	print("Username not recognised.")
end

The code above will work fine, however issues could occur if users of the extremely primitive system used capital letters in their names - for example if "Joe" was written in instead of "joe". This problem can be solved by using the string.lower function, which makes all characters in a string lowercase. A modification like the following should solve this problem:

1
2
3
4
5
6
7
8
9
io.write("Enter your username: ")
username = io.read()
username = string.lower(username)

if username == "joe" or username=="admin" then
	print("Access granted.")
else
	print("Username not recognised.")
end

The last logical operator we're going to be talking about in this tutorial is a little bit different. Instead of using the operator to conjoin two conditions, we use the operator to essentially flip something to its opposite state. This operator is called the 'not' operator. If we have anything that returns true, the not operator will change it to false, and the inverse is true for false being switched to true.

A nice way to think about it is that "not true" is false, and "not false" is true. As hinted at by the previous sentence, the 'not' operator in written in Lua by simply writing not before the thing you want to flip. If can be used in a similar sense to and and or in 'if' statements to flip a condition. Also remember that a basic true or false value will actually suffice fine as an 'if' statement condition, so something like the following would work fine:

1
2
3
4
5
boolean_variable = true

if not boolean_variable then --If not true (false)
	--Code here will never execute with boolean_variable being 'true'
end

Apart from this classic usage of not, which is commonly used for flipping boolean (true or false) variables and for flipping the return values of functions, the not operator can also be useful in other areas. There may, for example, be a situation in which our Lua script needs to toggle the value of a boolean variable with an unknown initial value. If it's true then we want it to be false, and if it's false then we want it to be true. We could write some 'if' statement logic to accomplish these simple goals, however a much more elegant solution would be to set the variable to not itself. Something like the following would do the job excellently:

1
2
3
4
boolean_variable = true
boolean_variable = not boolean_variable --Essentially toggle the variable state

print(boolean_variable) --Output the result