Sunday, 13 July 2014

Ruby - Nested If statements

Hey All!

Now that we have an idea of how to use If statements in our code, let’s look at how we might use multiple If statements together via nesting.

YouTube Channel: [WATCH, RATE, SUBSCRIBE]



It’s very likely you’ll have a condition you evaluate that won’t be the last nuance of the question. For example, you might ask what team someone is in but then need to know what business area they are assigned to. They could be in the testing team, but more specifically in the UI testing team. Knowing that could make a whole bunch of difference as to who knows… what tools they have access to, the SharePoint site they can use, etc.

Putting an If statement inside an If statement is the easiest way. Though caveat number 1 is they look messy (hey, pretty code is important!) and worse they can start to look confusing. Take the approach then when using nested If statements, keep them simple and limited. As we’ll discover, Ruby and other languages have tidier ways of doing things like Methods, Classes and even Arrays.

Let’s start with a straight forward If statement in the style we saw previously. In this example we use a mix of the evaluation styles we have available and a single then as a reminder from the last post. In your code, keep it consistent!

puts "Where are you from?"
location = gets.chomp.downcase

if location =~ /\A(london|f)\z/ then
  puts "OK, a big city..."
 
  elsif location == "scotland"
    puts "ach the noo!"

  elsif location == "pen y bont" or location == "bridge end"
    puts "A fun town, haven't been there in years"
   
  else
    puts "Aha, I thought you came from somewhere strange..."
 
end

The above locations are a bit broad, what if we wanted to respond differently given a person’s location? Say, having Pen Y Bont as a second question after asking if the user comes from Wales? Let’s change the above to ask about Wales first.

elsif ["Wales","wales"].include? location then

Now we’ll put the Pen y Bont part back in, using a nested If.

elsif ["Wales","wales"].include? location then
    puts "Which part? of Wales"
    country_part = gets.chomp.downcase

      if country_part == "pen y bont" or country_part == "bridge end"
        puts "A fun town, haven't been there in years"

      end

In this way we have a nested If statement that will only be called if the user comes from Wales. If so, we have another variable called country_part to capture which part of Wales, Bridegend in this case. Just like our ‘outer’ if, it’s an if-code-end format and yes you could add elsif and else in there too.

puts "Where are you from?"
location = gets.chomp.downcase

if location =~ /\A(london|f)\z/ then
  puts "OK, a big city..."
 
  elsif ["Scotland","scotland"].include? location
    puts "ach the noo!"

  elsif ["Wales","wales"].include? location then
    puts "Which part? of Wales"
    country_part = gets.chomp.downcase
   
      if country_part == "pen y bont" or country_part == "bridge end"
        puts "A fun town, haven't been there in years"
       
      elsif country_part =~ /\A(cardif)\z/
        puts "Nice Castle there..."
     
      else puts "Hmm... never been there! Ydych chi'n siarad Cymraeg?"
            #watch Google translate get that wrong...
                 
      end
     
  else
    puts "Aha, I thought you came from somewhere strange..."
 
end

Not bad, covers quite a bit and is still fairly readable. However, you’re probably already getting a sense of how a larger nested If statement will easily become difficult to read. Use with caution. Even with our current limited knowledge of Ruby we could be combining Arrays for data, with Case for control and sprinkling some If statements for a little decision making and it would be neater.

Bonus question: Can you spot the bug in the above code? It won’t fail as such, it’ll just give an  undesired response for an ‘odd’ input.

---------------------------------------------------------------------------------------------------
Spoiler:  if location =~ /\A(london|f)\z/ then
The f is an alternate that shouldn’t be there, copy and paste error! Was (flee|f), the user can type Flee or f and it will mean the same. Woops. Can you think of a way to use this feature?
----------------------------------------------------------------------------------------------------- 



Mark.

Read More

0 comments: