Ruby Programming/Syntax/Control Structures

Control Structures edit

Conditional Branches edit

Ruby can control the execution of code using Conditional branches. A conditional Branch takes the result of a test expression and executes a block of code depending whether the test expression is true or false. If the test expression evaluates to the constant false or nil, the test is false; otherwise, it is true. Note that the number zero is considered true, whereas many other programming languages consider it false.

In many popular programming languages, conditional branches are statements. They can affect which code is executed, but they do not result in values themselves. In Ruby, however, conditional branches are expressions. They evaluate to values, just like other expressions do. An if expression, for example, not only determines whether a subordinate block of code will execute, but also results in a value itself. If no block is executed, the if expression results in nil. For instance, the following if expression evaluates to 3:

 if true

Ruby's conditional branches are explained below.

if expression edit


 a = 5
 if a == 4
   a = 7
 print a # prints 5 since the if-block isn't executed

You can also put the test expression and code block on the same line if you use then:

 if a == 4 then a = 7 end
 if a == 4: a = 7 end
 #Note that the ":" syntax for if one line blocks do not work anymore in ruby 1.9. Ternary statements still work

This is equal to:

 a = 5
 a = 7 if a == 4
 print a # prints 5 since the if-block isn't executed

unless expression edit

The unless-expression is the opposite of the if-expression, the code-block it contains will only be executed if the test expression is false.


 a = 5
 unless a == 4
   a = 7
 print a # prints 7 since the unless-block is executed

The unless expression is almost exactly like a negated if expression:

 if !expression # is equal to using unless expression

The difference is that the unless does not permit a following elsif. And there is no elsunless.

Like the if-expression you can also write:

 a = 5
 a = 7 unless a == 4
 print a # prints 7 since the unless-block is executed

The "one-liners" are handy when the code executed in the block is one line only.

if-elsif-else expression edit

The elsif (note that it's elsif and not elseif) and else blocks give you further control of your scripts by providing the option to accommodate additional tests. The elsif and else blocks are considered only if the if test is false. You can have any number of elsif blocks but only one if and one else block.


 if expression
   ...code block...
 elsif another expression
   ...code block...
 elsif another expression
   ...code block...
   ...code block...

short-if expression (aka ternary operator) edit

The "short-if" statement provides you with a space-saving way of evaluating an expression and returning a value.

The format is:

 result = (condition) ? (expression-if-true) : (expression-if-false)

It is also known as the ternary operator and it is suggested to only use this syntax for minor tasks, such as string formatting, because of poor code readability that may result.

 irb(main):037:0> true ? 't' : 'f'
 => "t"
 irb(main):038:0> false ? 't' : 'f'
 => "f"

This is very useful when doing string concatenation among other things.


 a = 5
 plus_or_minus = '+'
 print "The number #{a}#{plus_or_minus}1 is: #{plus_or_minus == '+' ? (a+1).to_s : (a-1).to_s}."

Also, this can be written as:

 result = if condition then expression-1 else expression-2 end

Assignments can be made as:

 result = (value-1 if expression-1) || (value-2 if expression-2)

case expression edit

An alternative to the if-elsif-else expression (above) is the case expression. Case in Ruby supports a number of syntaxes. For example, suppose we want to determine the relationship of a number (given by the variable a) to 5. We could say:

 a = 1
 when a < 5 then puts "#{a} is less than 5"    
 when a == 5 then puts "#{a} equals 5"   
 when a > 5 then puts "#{a} is greater than 5" 

Note that, as with if, the comparison operator is ==. The assignment operator is =. Though Ruby will accept the assignment operator:

   when a = 5 then puts "#{a} equals 5"   # WARNING! This code CHANGES the value of a!

this is not what we want! Here, we want the comparison operator.

A more concise syntax for case is to imply the comparison:

 case a
 when 0..4 then puts "#{a} is less than 5"    
 when 5 then puts "#{a} equals 5" 
 when 5..10 then puts "#{a} is greater than 5" 
 else puts "unexpected value #{a} "         # Just in case "a" is bigger than 10 or negative.

Note: because the ranges are explicitly stated, it is a good coding practice to handle unexpected values of a. This concise syntax is perhaps most useful when we know in advance what values to expect. For example:

 a = "apple"
 case a
 when "vanilla" then "a spice"    
 when  "spinach" then "a vegetable" 
 when "apple" then "a fruit" 
 else "an unexpected value"

If entered into IRB this gives:

 => "a fruit"

Other ways to use case and variations on its syntax may be seen at Linuxtopia Ruby Programming [1]

Loops edit

while edit

The while statement in Ruby is very similar to if and to other languages' while (syntactically):

while <expression>
  <...code block...>

The code block will be executed again and again, as long as the expression evaluates to true.

Also, like if and unless, the following is possible:

<...code...> while <expression>

Note the following strange case works...

 line = readline.chomp while line != "what I'm looking for"

So if local variable line has no existence prior to this line, on seeing it for the first time it has the value nil when the loop expression is first evaluated.

until edit

The until statement is similar to the while statement in functionality. Unlike the while statement, the code block for the until loop will execute as long as the expression evaluates to false.

until <expression>
  <...code block...>

Keywords edit

return edit

return value causes the method in which it appears to exit at that point and return the value specified.

Note that if a method has no return statement then the value of the last statement is implicitly returned.