1. Computing

Conditional Statements

By

If the car is stopped and the safety belt is not fastened then play a beeping sound. If the temperature of the engine exceeds a certain level then light the temperature indicator light on the dash. These are some common tasks a car computer might perform, and they're all in the form of "if...then" statements, also known as conditional statements. All computer programs need conditional statements, they are what make computer programs more than just number crunchers. And Ruby has just a few conditional statements for you to learn.

If X then Y else Z

This is the conditional statement you're probably most familiar with. Virtually all computer languages have this construct. If the boolean expression X is true then perform X, otherwise perform Z. Besides Ruby's slightly different views on what is and is not true, there are no surprises here. Any expressions can be used in place of X, even those using boolean operators.

The following example is one of the first programs I ever learned to write (in BASIC on the Commodore 64). It's a simple number guessing game. The computer chooses a random number from 1 to 100 and you give it guesses. If your guess is higher then it prints "too high." And if your guess is lower, then it prints "too low." Notice the conditional statements? This is a very straightforward example of their use. Also, little did I know but this teaches how to do a binary search, edutainment at its best.


#!/usr/bin/env ruby

number = rand(100)
num_guesses = 0

puts "I'm thinking of a random number from 1 to 100"
puts "Can you guess it?"

loop do
  print "What is your guess? "
  guess = gets.chomp.to_i
  num_guesses += 1

  if guess == number
    puts "You got it!"
    puts "It took you #{num_guesses} guesses."
    exit
  end

  if guess > number
    puts "Too high."
  end

  if guess < number
    puts "Too low."
  end
end

This demonstrated the most basic form of the 'if' statement. However, there's also an if/else statement that could be used to make this program a bit more compact. Note that there are three if statements that all test the 'guess' variable. We could combine them into one if/else statement. Note that we even remove one of the conditional statement, since if guess is neither greater than or less than the number, it must be equal to the number.


if guess > number
  puts "Too high."
elsif guess < number
  puts "Too low."
else
  puts "You got it!"
  puts "It took you #{num_guesses} guesses."
  exit
end

One thing to note here is that Ruby does not use "else if." Ruby has a separate elsif keyword that must be used. Other languages do this differently, but thankfully this will throw a syntax error if you get it wrong, so there will be no silent error.

Unless, a Backwards If

If the guess is not equal to the number, then print too high or too low. To some, statements like this conditional aren't quite right. If you're testing for a negative in the boolean statement, it just doesn't read all that well. Ruby provides another conditional statement to accommodate you if this is the case. The unless keyword is exactly like the if keyword, except the block is only executed if the boolean expression is false. The unless keyword is usually only used for simpler expressions. There is not unless/else version of this statement, though there is an unless/else.

The following is one way the conditionals from the number guessing game can be rewritten using the unless conditional. The unless statement tests whether the guess is equal and, if not, displays either too high or too low. Otherwise, end the game.


unless guess == number
  if guess > number
    puts "Too high."
  elsif guess < number
    puts "Too low."
  end
else
  puts "You got it!"
  puts "It took you #{num_guesses} guesses."
  exit
end

When using the unless conditional, make sure that the boolean expression is as simple as possible. Once you get into 'unless X && Y || Z' type expressions, then the reversed logic becomes harder to read, defeating the purpose of using the unless keyword to begin with. A good rule of thumb is that the boolean expression in an unless statement should be a single method call or boolean value, or a simple boolean expression with no negations. Anything more complicated and it just confuses things, use the if statement instead. Some will go as far as saying that else should not be used as, but if you choose to use unless/else is a matter of style.

Good Code is Terse Code

Good code is often terse code (but terse code is not necessarily good code). Terse code says exactly what needs to be said, but no more. Ruby provides a number of ways to write terse code, but without going to the lengths of the symbol-soup that Perl programs become. One of these ways is the postfix conditional statement. If there is only a single statement inside the conditional statement, then the if statement can come after the statement and it can be written on all one line. In other words, instead of composing a formal "if X then do Y" statement, you can simply say "do Y if X." It's terse, and it often reads much easier than the larger form of the conditional statements. The following is yet another rewrite of the guessing game's conditionals. The unless statement is unchanged, but the two if statements inside use the postfix syntax.


unless guess == number
  puts "Too high." if guess > number
  puts "Too low." if guess < number
else
  puts "You got it!"
  puts "It took you #{num_guesses} guesses."
  exit
end

An Added Bonus

As an added bonus, Ruby's if statements (and unless) evaluate to whatever the last statement in the path taken evaluates to. In other words, you can use if statements in things like methods to determine a return value, or variable assignments. So, you can rewrite our number guessing game yet again to take advantage of this. Though I wouldn't necessarily do it this way, it just can be done this way.


unless guess == number
  message = if guess > number
              "Too high"
            else
              "Too low"
            end
  puts message
else
  puts "You got it!"
  puts "It took you #{num_guesses} guesses."
  exit
end
  1. About.com
  2. Computing
  3. Ruby
  4. Beginning Ruby
  5. Control Structures
  6. Conditional Statements

©2014 About.com. All rights reserved.