Ruby: If Statements
One of the most powerful features present in most programming and scripting languages is the ability to change the flow of the program as certain conditions change. The simplest form of flow control and logic in Ruby is called an "if statement" (or technically speaking in Ruby, since everything is an expression, an "if expression").
These 'if' experssions essentially check whether a condition is true or not. In Ruby they are created by writing the if
keyword, followed by a condition, optionally followed by the then
keyword, then the code you want to execute if the condition is true, and then finally the end
keyword to end the structure. So they should look something like the following:
1 2 3 |
|
As mentioned though, the then
is often dropped from the structure as it simply provides separation from the condition and the code to execute - one-line 'if' statements require the then
to separate these, but multi-line ones like we'll be writing most of the time can use a new line to separate the condition and code.
1 2 3 |
|
From here the obvious question is: "How do I formulate a condition?". Well firstly, it's important to note that any expression that evaluates to a 'true' or 'false' value can be in the place of the condition there -- that includes boolean variables and method calls! So the following would always output "Hello" as 'some_variable' will, in this case, always evaluate to true:
1 2 3 4 5 |
|
"Real" conditions, for example comparing one variable to another, can be created by using 'conditional' or 'comparison' operators. These are operators that are made for comparing things, and when values are present at both sides of the operator, this will result in a 'true' or 'false' value. The basic conditional operators are:
==
- Is equal to!=
- Is not equal to>
- Is greater than<
- Is less than>=
- Is greater than or equal to<=
- Is less than or equal to
So to put these into actions, let's create a basic script which checks if the user is an administrator of our made-up system – it's not going to be very secure or really good for anything at the moment, but it'll be a good example to make sure we know this stuff.
The easiest way to authenticate a user is probably via a username and password, so the first thing our example script should do is ask for this data. Luckily we already know how to do this using puts
and gets
, however in this example it's more suitable to use print
instead of puts
- the two essentially do the same thing, however puts
appends a newline to the output whereas print
does not. So let's write this portion of the script!
1 2 3 4 |
|
From here, the 'if' statements need to do their magic. In this case we can just hard-code the administrator username and password into our script (not a good idea in a real system, but it'll work fine here). So first our comparison between the administrator username and what the user actually entered:
1 2 3 |
|
From here we want to check if the password is correct. If statements and other similar structures can actually be nested, so in this case it might be a nice idea to put another 'if' statement inside this one to check if the password is correct, like so:
1 2 3 4 5 |
|
You can see I've added a little puts
message so that we can tell when the username and password were correct ("foo" and "bar"). If you take our code so far and put it into a ruby file and run it, you should see that our special message only displays when "foo" and "bar" are entered! But what do we do if we want something to happen when the username and password are entered wrongly? Perhaps we want to display a message telling the user that the details they entered were wrong. We could write a few 'if' statements that use the "is not equal to" (!=
) operator, however this seems like a waste of processing power given that we've already determined if the credentials are correct or not. This is where 'else' statements come in.
After an 'if' statement, just before 'end', you can introduce an 'else' clause. The code in this clause will execute if the 'if' statement was not true (and if none of the other 'if's in that chain were true, but we'll get on to this in a minute). These are accomplished using the else
keyword where end
would usually be, and moving end
to the end. The syntax is as follows:
1 2 3 4 5 |
|
In our example we could easily utilise this functionality to output errors to the user in our example program:
1 2 3 4 5 6 7 8 9 |
|
As I previously touched on however, you can actually have more than one condition in an 'if' statement "chain", in which case the 'else' clause will only happen if none of the conditions are true. A nice way to show this in our example is if our system had multiple users. Perhaps we want to add a 'guest' user which doesn't require a password. We can add these "extra conditions" by using what is called an 'else if', written via the elsif
keyword. Reading 'if' chains out-loud often makes some sense of them: "If this, do this, else if this, do this, else if this, do this, else, do this", this should also make obvious the fact that the next item in the chain will only be proceeded to if the previous is false – so elsif
s are only checked if the primary condition is false, and else
s are only checked if everything else is false. The syntax of an 'elsif' in a chain is as follows:
1 2 3 4 5 6 7 |
|
With this, it should be fairly easy to create a guest user:
1 2 3 4 5 6 7 8 9 10 11 |
|
You could argue that asking the 'guest' user for their password isn't necessary, and this could be fixed by moving the password prompt and gets
into the administrator 'if' statement, and feel free to see if you can do this, however it's not important for this example.
The best way to learn about 'if' statements is really to play around with them. A good idea might be to try creating a script which takes the score for an exam out of 100 and then outputs a grade depending on the score entered (within certain grade boundaries – the greater than and less than comparisons should be useful here!). The only problem you might run into in creating this script is the comparison of different data types. If you try to compare a string variable (for example something received from gets
) with an integer (like 1), then you will run into problems. As such, you might want to explore to to_i
and to_s
methods. The former will likely want to be used in this example and is a method to convert strings to integers, while the latter is less useful in this example however may be more useful in others, and converts integers to strings.
You could use the to_i
method on the gets.chomp
itself (probably the better option here), or if you wanted you could use it in every condition with comparison to an integer. The former is shown, basically, below:
1 2 3 4 5 6 |
|
Moving away from this a bit, which hopefully you should now understand and be able to use, there is also some more flexibility and some more shorthand options in this 'if' functionality. Firstly, a basic 'if' can actually be after the line that should be executed if it's true, like so:
1
|
|
Similarly, a basic 'if' statement can be compressed to one line if the then
keyword is used to replace the newline:
1
|
|
Ruby also has something called a "ternary operator" which provides a shortcut way of making basic comparisons. The syntax of this is a condition, followed by a question mark, followed by the expression that should be given if the condition is true, followed by a colon, followed by the expression that should be given if the condition is false, as can be seen below:
1
|
|
This is useful when a quick and compact decision between expressions is necessary, for example the following:
1 2 3 4 |
|