Computer programs, like life itself, are full of difficult decisions waiting to be made. Things like “If I stay in bed, I will get more sleep, else I will have to go to work; if I go to work, I will earn some money, else I will lose my job,” and so on. You’ve already performed a number of if
tests in previous programs. To take a simple example, this is from the Tax calculator in Chapter 1:
if (subtotal < 0.0) then subtotal = 0.0 end
In this program, the user was prompted to enter a value, subtotal
, that was then used in order to calculate the tax due on it. If the user, in a fit of madness, enters a value less than 0, the if
test spots this since the test (subtotal < 0.0)
evaluates to true, which causes the body of the code between the if
test and the end
keyword to be executed; here, this sets the value of subtotal
to 0.
A simple test like this has only one of two possible results. Either a bit of code is run or it isn’t, depending on whether the test evaluates to true or not. Often, you will need to have more than two possible outcomes. Let’s suppose, for example, that your program needs to follow one course of action if the day is a weekday and a different course of action if it is a weekend. You can test these conditions by adding an else
section after the if
section, like this:
if_else.rb
if aDay == 'Saturday' or aDay == 'Sunday' daytype = 'weekend' else daytype = 'weekday' end
Like many other programming languages, Ruby uses one equal sign (=
) to assign a value and two (==
) to test a value.
The if
condition here is straightforward. It tests two possible conditions: if the value of the variable aDay
is equal to the string “Saturday” and if the value of aDay
is equal to the string “Sunday.” If either of those conditions is true, then the next line of code executes daytype = 'weekend'
; in all other cases, the code after else
executes daytype = 'weekday'
.
When an if
test and the code to be executed are placed on separate lines, the then
keyword is optional. When the test and the code are placed on a single line, the then
keyword is obligatory:
if_then.rb
if x == 1 then puts( 'ok' ) end # with 'then' if x == 1 puts( 'ok' ) end # syntax error!
In Ruby 1.8, a colon character (:
) was permitted as an alternative to then
. This syntax is not supported in Ruby 1.9:
if x == 1 : puts( 'ok' ) end # This works with Ruby 1.8 only
An if
test isn’t restricted to evaluating just two conditions. Let’s suppose, for example, that your code needs to work out whether a certain day is a working day or a holiday. All weekdays are working days; all Saturdays are holidays, but Sundays are only holidays when you are not working overtime. This is my first attempt to write a test to evaluate all these conditions:
and_or_wrong.rb
working_overtime = true if aDay == 'Saturday' or aDay == 'Sunday' and not working_overtime daytype = 'holiday' puts( "Hurrah!" ) else daytype = 'working day' end
Unfortunately, this doesn’t have quite the effect intended. Remember that Saturday is always a holiday. But this code insists that Saturday is a working day. This is because Ruby takes the test to mean “If the day is Saturday and I am not working overtime or if the day is Sunday and I am not working overtime,” whereas what I really meant was “If the day is Saturday or if the day is Sunday and I am not working overtime.” The easiest way to resolve this ambiguity is to put parentheses around any code to be evaluated as a single unit, like this:
and_or.rb
if aDay == 'Saturday' or (aDay == 'Sunday' and not working_overtime)