Ruby 104: Flow Control & Conditionals
Comparisons
Equality comparisons can be used on all objects, including Strings
, Integers
, Floats
, Arrays
, Hashes
, etc:
- ==
(equal to?)
- !=
(not equal to?)
Numeric comparisons are used primarily on Integers
and Floats
:
- >
(greater than?)
- <
(less than?)
- >=
(greater than or equal to?)
- <=
(less than or equal to?)
The “result” of a comparison is known as a boolean. There are only two kinds of boolean object:
- true
- false
1 2 3 4 5 | 1 > 0 # => true "hello" == "hello" # => true |
Flow Control
Conditionals
if
and else
allow you to control the flow of your program. This means that they allow you to define which lines of code will execute, and which will be skipped.
1 2 3 4 5 | if boolean_value code end additional_code |
When you use an if
, the code
that follows it (until the end
) will only be executed if the boolean_value
is true
. Additionally, you may add else
before the end
:
1 2 3 4 5 6 7 | if boolean_value code else other_code end additional_code |
In this case, when boolean_value
is false
, then other_code
will be executed. Otherwise, it will be skipped. When you have an if
and an else
only one or the other of code
or other_code
will be executed, and that is determined by the value of boolean_value
.
1 2 3 4 5 6 7 8 9 10 11 | puts "Hey! What’s your name?" response = gets.chomp is_my_name = response.downcase == "computer" if is_my_name puts "Weird, that's my name too. Small world!" else puts "Wacky name!" end puts "Well, it was nice to meet you #{response}." |
1 2 3 4 5 | if 1 > 0 # do something else # do something different end |
Negating Comparisons
Ruby has an unless
keyword that works just like if
, but in the reverse way.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | puts "What is your favorite animal?" fav_animal = gets.chomp if fav_animal.downcase == "camel" puts "I also love camels!" else puts "That's a great animal, but I love camels the most." end # The following code works identically to the above unless fav_animal.downcase == "camel" puts "That's a great animal, but I love camels the most." else puts "I also love camels!" end |
The if
block executes if the conditional evaluates as true
. The unless
block executes if the conditional evaluates as false
.
Another way to “negate” a conditional is to use the !
(not) operator. This should be placed just before a boolean value, or a comparison. When combined with a comparison the comparison should be enclosed in parentheses:
1 2 3 4 5 6 7 8 9 10 11 | puts "What day of the week is it?" day_of_week = gets.chomp puts "What did you have for lunch today?" lunch = gets.chomp if day_of_week.downcase == "tuesday" if !(lunch == "tacos") puts "Taco Tuesdays are my favorite, though!" end end |
Compound Conditions
Comparisons are often combined. Combinations can take one of two forms, and and or. When you combine with and
, both comparisons must be true
for the entire combination to be true
. By combining with or
, when either of the comparisons are true
, the entire combination is true
:
- &&
(and)
- ||
(or)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | puts "What is your first name?" first_name = gets.chomp puts "What is your last name?" last_name = gets.chomp if first_name.length > 8 if last_name.length > 10 puts "Your name is considerable!" end end # This is the same as the above if first_name.length > 8 && last_name.length > 10 puts "Your name is considerable!" end |
1 2 3 4 5 6 7 8 9 10 11 12 | if command == "add" puts "We're adding numbers." end if command == "+" puts "We're adding numbers." end # This is the same as the above if command == "add" || command == "+" puts "We're adding numbers." end |
Complex conditionals
The if/else/end
code we’ve written above is the standard and simplest form of a conditional. It is possible to extend this form with one or more elsif
lines:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | if command == "add" || command == "+" puts "We're adding numbers" else if command == "subtract" || command == "-" puts "We're subtracting numbers" else if command == "multiply" || command == "*" puts "We're multiplying numbers" end end end # This is equivalent to the above if command == "add" || command == "+" puts "We're adding numbers" elsif command == "subtract" || command == "-" puts "We're subtracting numbers" elsif command == "multiply" || command == "*" puts "We're multiplying numbers" end |
This can be very useful, when you have more than one elsif
line, because the indentation, or nesting, can quickly become very deep, and more difficult to understand.
Simplifying really complex conditionals
When you have several elsif
lines within a single if
, there’s a way to write each conditional, with much less repetition:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | if command == "add" || command == "+" puts "We're adding numbers" elsif command == "subtract" || command == "-" puts "We're subtracting numbers" elsif command == "multiply" || command == "*" puts "We're multiplying numbers" elsif command == "divide" || command == "/" puts "We're dividing numbers" elsif command == "exponify" || command == "**" puts "We're exponentiating numbers" elsif command == "sqrt" puts "We're finding the square root of a number" else puts "What do you want from me?!" end |
The above code works, but it’s kinda messy. We can trim it by using the case/when
syntax:
~~~ruby
case command
when “add”, “+”
puts “We’re adding numbers”
when “subtract”, “-“
puts “We’re subtracting numbers”
when “multiply”, “*”
puts “We’re multiplying numbers”
when “divide”, “/”
puts “We’re dividing numbers”
when “exponify”, “**”
puts “We’re exponentiating numbers”
when “sqrt”
puts “We’re finding the square root of a number”
else
puts “What do you want from me?!”
end
~~~
Conditional Loops
### Wait a while
Execute the iterator while
the condition is true.
1 2 3 4 5 6 | i = 0 while i < 4 puts i i += 1 end |
The above code will output the values of i until i is no longer less than 4, resulting in the following output: ~~~ 0 1 2 3 ~~~
1 2 3 4 5 6 7 8 | command = gets.chomp while command != "add" && command != "+" puts "Please tell me to add (+)!" command = gets.chomp end puts "OMG It's about time!" |
Make it clearer by using Until
Execute the iterator until
the condition is true.
1 2 3 4 5 6 | i = 0 until i == 4 puts i i += 1 end |
The above code will output the values of i until i is equal to 4, resulting in the following (equivalent to the above) output: ~~~ 0 1 2 3 ~~~
1 2 3 4 5 6 7 8 | command = gets.chomp until command == "add" || command == "+" || command == "subtract" || command == "-" puts "Please tell me to add (+) or subtract (-)!" command = gets.chomp end puts "OMG It's about time!" |
Make it clearer by using include?
1 2 3 4 5 6 7 8 | command = gets.chomp until ["add", "+", "subtract", "-"].include? command puts "Please tell me to add (+) or subtract (-)!" command = gets.chomp end puts "OMG It's about time!" |