Ruby Programming/Syntax/Control Structures
Control Structures
editConditional Branches
editRuby 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 3 end
Ruby's conditional branches are explained below.
if expression
editExamples:
a = 5 if a == 4 a = 7 end 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 #or 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
editThe unless-expression is the opposite of the if-expression, the code-block it contains will only be executed if the test expression is false.
Examples:
a = 5 unless a == 4 a = 7 end 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
editThe 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.
Syntax:
if expression ...code block... elsif another expression ...code block... elsif another expression ...code block... else ...code block... end
short-if expression (aka ternary operator)
editThe "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.
Example:
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
editAn 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 case 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" end
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. end
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" end
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
editwhile
editThe while
statement in Ruby is very similar to if
and to other languages' while
(syntactically):
while <expression> <...code block...> end
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
editThe 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...> end
Keywords
editreturn
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.