Learn Ruby and rails from rails guru
Posts tagged if else
Quick Ruby Tutorials-4, Decision Making
Apr 17th
This is a continuation of the following series of posts
Quick Ruby Tutorials-1
Quick Ruby Tutorials-2
Quick Ruby Tutorials-3
Currently our Dog eats, anything and everything given to it. Lets give our dog some choice.
if you give the dog chocolate, it should ask for some more, otherwise it should behave normally.
def eat(food="bone")
puts "I am eating #{food}"
if (food == "chocoloate") # parnthesis are optional
puts "Give me some more"
end
end
end
d = Dog.new
d.eat("bread") # I am eating bread
d.eat("chocolate")
#I am eating chocolate
#Give me some more.
In the above code, we are using the If statement to make decisions ie to execute a certain part of code only if a particular condition is satisfied.
Syntax of if statement is as follows
# code1 which executes when expression1 is true
elsif (<expression2>)
# code2 which executes when expression2 is true and expression1 is false
elsif (<expression3>)
# code3 which executes when expression3 is true and expression 1 & 2 are false
else
#code 4 which executes when expression 1&2&3 are false.
end
The expression can be any ruby statement. If the output of the expression is true/not nil then the corresponding code is executed other wise it moves to the next elsif/else
So above
if expression1 one evaluates to true then code 1 is executed
if expression1 is false and expression2 is true then code2 is executed
…
if no expression is evaluated to true then the code in the else block is executed.
The elsif and the else block are optional.
There can be multiple elsif blocks but only one else block.
Else block does not accept any argument.
The else block is the last block in the if statment. After that there can be no further elsif/else
The if statement ends with a “end” irrespective of then number of elsif.
There can be different forms of if statements given below
#code which is executed if expression is true
end
A short form for this is this is
This is called a one liner if statement
Example:
puts "Drive Slow" if speed > 60 # Drive Slow
time = "afternoon"
puts "Good Morning" if time == "morning" #
The one liner if statements are very useful when there is no elsif/else part and the body of the if is just a single line of ruby code.
#code1
else
#code2
end
Here one of the parts code1 or code2 is always executed.
#code1
elsif expression2
#code2
end
Here if expression1 is true then code1 is executed, if expression1 is false but expression2 is true then code2 is executed. If both are false then nothing is executed.
More about expressions.
Again: The body of the if statement is executed if the expression evaluates to true or a non nil value which is not false.
Or
The body of the if statement is not executed if the expression evaluates to false or nil.
We will demonstrated this using one liner if statement.
In the body of the one liner if, we will keep a puts statement.
So if there is any output on screen, then we know that the expression has been satisfied.
puts "this will not print" if 2 > 3 #
puts "2 is less than 3" if 2 < 3 # 2 is less than 3
puts "this will not print" if 3 < 2 #
puts "3 which is a non nil object evaluates to true" if 3 #3 which is a non nil object evaluates to true
puts "true" if true # true
puts "this will not print" if false #
puts "this will not print" if nil
puts "3 is equal to 3" if 3 == 3 # 3 is equal to 3
puts "x is equal to 3" if x = 3 # x is equal to 3
puts "3 is not equal to 2" if 3 != 2 #3 is not equal to 2
Above we have used constants in the expression. This was to keep things simple.
We can use variables, method calls, and their combination in an expression.
Every expression can be a combination of objects, methods calls, operators.
2 important things to note from the above example are:
we can check whether an variable/object x exists by doing
The if statement is only executed when the object x exists ie when its value is not nil.
Second thing is, in case of an assignment operation, the output of the expression is the value which is assigned.
So if we do
x = y
then the output of this expression is y.
Coming back to the dog example:
Lets modify our Dog class so that,
if you give it “banana” to eat, the dog should not eat. It should ask for something else.
def eat(food="bone")
if food == "banana"
puts "I do not eat banana, give me something else"
else
puts "I am eating #{food}"
end
if food == "chocolate"
puts "Give me some more"
end
end
end
d = Dog.new
d.eat("banana") #I do not eat banana, give me something else
d.eat("bread") # I am eating bread
d.eat("chocolate")
#I am eating chocolate
#Give me some more.
Note that the condition if food == chocolate is being tested for even if the food is banana. We should move that loop into the body of if. This is called nested if ie an if inside if.
def eat(food="bone")
if food == "banana"
puts "I do not eat banana, give me something else"
else
puts "I am eating #{food}"
if food == "chocolate"
puts "Give me some more"
end
end
end
end
d = Dog.new
d.eat("banana") #I do not eat banana, give me something else
d.eat("bread") # I am eating bread
d.eat("chocolate")
#I am eating chocolate
#Give me some more.
It would much cleaner if we add a one liner if condition here, that makes it much more readable
def eat(food="bone")
if food == "banana"
puts "I do not eat banana, give me something else"
else
puts "I am eating #{food}"
puts "Give me some more" if food == "chocolate"
end
end
end
Lets add some more conditions, If you give it bone then it should say “great, u made my day”.
if you give it “sandwich” then it should say “mmmmmmmmmmmm, I have never eaten like this one before”
if you give it milk, then it should tell “Thankyou, I will become a strong dog after drinking milk”
Previous conditions also apply. It should not say “I am eating xyz” along with other statements as above.
def eat(food="bone")
if food == "banana"
puts "I do not eat banana, give me something else"
elsif food == "chocoloate"
puts "Give me some more"
elsif food == "bone"
puts "Great, you made my day"
elsif food == "sandwich"
puts "mmmmmmmmm I have never eaten like this one before"
elsif food == "milk"
puts "Thank you, I will become a strong dog after drinking milk"
else
puts "I am eating #{food}"
end
end
end
We replace this by a case statement.
Case statement is an alternative for a if statement.
If the output of a calculation depends on a value of an object, and the number of cases are high then it can become very cumbersome if you use if statement. It is much easier doing the same using a case statement.
Syntax for the case statement is :
when match_1 then result_1
when match_2 then result_2
when match_3 then result_3
when match_4 then result_4
else result_5
end
</end>
<code lang="ruby">
class Dog
def eat(food="bone")
message = case food
when "banana" then "I do not eat banana, give me something"
when "chocolate" then "Give me some more"
when "bone" then "Great, you made my day"
when "sandwich" then "mmmmmmmmm I have never eaten like this one before"
when "milk" then "Thank you, I will become a strong dog after drinking milk"
else "I am eating #{food}"
end
puts message
end
end
So this looks much cleaner the the code with if statement.
Note how we collected the output of the case statement in the variable message, and then printed the variable. We could have instead printed the value in the case statement it self as done in the if statement.
But this one is better, as if later, instead of printing the message on screen, I just want to return the message, or store it in a file then I would need to just change one line. Instead if we had embedded the puts in the case itself, then we would need to change many lines.
The code which adapts to a change, with lesser lines of changes, in lesser number of files, is a better code.
Let us take a different scenario:
A dog will reject the following items: banana, mango
It will accept the following : biscuit, bread, milk
def eat(food="bone")
if food == "banana" || food == "mango"
puts "I do not eat #{food}, give me something else"
elsif food == "milk" || food == "bread" || food == "biscuit"
puts "thank you for giving me #{food}"
else
puts "Can this be eaten?"
end
end
end
d = Dog.new
d.eat("banana") #I do not eat banana, give me something else.
d.eat("bread") # thank you for giving me bread.
d.eat("ball") # can this be eaten?
Now,if this list of eatables gets very long( the food which dog can eat and once which it cannot), then the program would become very cumbersome.
Let us use some magic of arrays to this.
@@good_food = ["milk", "bread", "biscuit","bone"]
@@bad_food = ["banana", "mango"]
def eat(food="bone")
if @@bad_food.include? food
puts "I do not eat #{food}, give me something else"
elsif @@good_food.include? food
puts "thank you for giving me #{food}"
else
puts "Can this be eaten?"
end
end
end
Here we are defining 2 class variables: @@good_food and @@bad_food. We initialize each of these to an array holding the respective food types.
In the if statement we use a method include?(x) on the array object.
This method returns true if x is present in the array else it returns false.
For a complete list of methods present in the array classs go to: http://ruby-doc.org/core/classes/Array.html
One fine day our dogs realize that global warming is increasing a high rate.
All the scientist dogs get together and do a research on this. They come to a conclusion that the major cause of the global warming is non vegetarianism(http://www.goveg.com/environment.asp).
So they all decide to go veg
Now if you gave our veg dogs a bone or meat to eat, should reject it, telling that stop non veg,stop global warming!.
Let us modify our code to do the same.
@@non_veg_food = ["bone","meat"]
@@good_food = ["milk", "bread", "biscuit"]
@@bad_food = ["banana", "mango"]
def eat(food="bone")
if @@bad_food.include? food
puts "I do not eat #{food}, give me something else"
elsif @@good_food.include? food
puts "thank you for giving me #{food}"
elsif @@non_veg_food.include? food
puts "Go Veg, Stop Global Warming!"
else
puts "Can this be eaten?"
end
end
end
dog = Dog.new
dog.eat("bone") #Go Veg, Stop Global Warming!
So, by now our dogs have become very choosy. You can go ahead and do the following extensions:
- Add methods to the class to modify(add/remove) the food choices of the dog
- Currently all our dogs have the same choices, add functionality so that each dog can have their own choices, they may have some default choices when the are born.
- Let the food habits of a dog develop automatically: When a dog is given a food to eat when it is hungry, add the foo to the good food list, when a dog is given food to eat when it is not well, or when it is not hungry then add the food to bad food list.
These are just ideas, you can try whatever comes to your mind, be creative
.
Share

