Now that we can get input from our users, we can start to make our programs smart, by behaving differently based on different conditions.
To do this, we need to add a new grammar to our toolbox: the
end keywords. Here’s how it looks:
Try running this program a few times and see how it behaves.
The anatomy of an
if statement is:
if condition # code that runs if the condition is true end
if, on the same line, comes any Ruby expression, which is evaluated until only one piece of data is left.
conditionis “truthy”, then the code on the lines between the
endkeywords is executed.
conditionis “falsy”, then the code on the lines between the
endkeywords is ignored.
endkeyword and continues on.
if requires a matching
end, and forgetting it is a very common mistake.
My advice: type the
end immediately after typing the
if so that you don’t forget it; then worry about typing the condition, and the code that comes on the lines between the
if and the
(While you’re at it, indent the code on the lines between by two spaces so that it is visually clear what’s inside the
Why did I say “truthy” and “falsy” instead of just
false? Because many — most — Ruby expressions return values other than
false. Any expression can appear next to an
if, and some will cause the code inside the
if statement to execute (these values are known as “truthy”) and some will not (these are “falsy”).
In the REPL below, try replacing
lucky_number.odd? with each of the following. Before clicking “run” for each one, ask yourself, do you expect to see the output
"The condition is truthy." or not?
For how many of the above did you correctly predict the output? What did you learn about what objects count as truthy and what objects count as falsy in Ruby?
It turns out that only
nil are falsy. All other objects in Ruby are truthy — even
That said, we’ll mostly use expressions after
if that return
false. There are lot of methods that are designed to do this; we’ve seen
.even?, but there are a lot more.
For example, most classes have ways to compare instances of the class to one another:
1 < 2 # "1 is less than 2" 2 < 1 # "2 is less than 1" 24*365 > 10000 # There are more than 10,000 hours in a year 1 == 1 # "1 is equivalent to 1" 1 == 2 # "1 is equivalent to 2" 1 <= 2 # "1 is less than or equal to 2" 1 >= 2 # "1 is greater than or equal to 2" 1 != 1 # "1 is NOT equivalent to 1" 1 != 2 # "1 is NOT equivalent to 2" "apple" < "banana" "apple" > "banana" "apple" == "banana" "apple" != "banana"
Note the difference between the equivalence operator — two equals signs,
== — and the variable assignment operator — one equals sign,
=. Mixing up the two of them is probably the most common typo programmers make. Don’t say I didn’t warn you!
We can also have multibranch
if statements, where we specify fallback conditions to check and code to execute if the first condition is falsy:
ein the middle of the
elsefallback branch is executed; but you don’t have to have one if you don’t want one.
Inside a branch of an
if statement, you can have as many lines of code as you want — and you can even have whole other multi-branch if statements, if that’s what you need.
Finally, another handy thing to have in your toolbelt are the logical operators
&& (AND) and
|| (OR). These allow you to combine conditions; try these combined conditions out below:
3.odd? && 4.even? 3.odd? && 4.odd? 3.even? && 4.odd? 3.odd? || 4.even? 3.odd? || 4.odd? 3.even? || 4.odd?
&& is stricter than
||; both comparisons have to be true in order for the whole statement to be true when combined with
&&; either one being true is sufficient for
Can you create a simple Rock, Paper, Scissors game?
Now, can you create a better version of the game, where the computer chooses its move randomly instead of always choosing scissors?