Statements

Ruby is a structured language, executes blocks of statements, which are delimited by the words "begin .. end" or "then .. end". After a conditional instruction the "then" statement can be omitted, but not if the statements are on the same line as the condition.

A block returns a value, which is the result of last executed expression.

Conditional Statements

Loop Statements

The blocks executed many times are between the "do .. end" statements, or curly brackets. The "do" keyword can be omitted. The "do" (or bracket) beginning the loop block must be on the same line as the "loop" keyword.

Exception Handling

The raise and rescue statements are used for exception handling; the "raise" statement throws an exception, which is an instance of the "Exception" class. There are many pre-defined exception classes, the default being "RuntimeError".

The "rescue" statements define blocks which are executed if an exception of a specified class is raised. The last raised exception is saved in the global variable: "$!" .

The general form of the "begin ... rescue .. end" block is:

begin
  ...
  raise exception_name

rescue Exception_class,Exception_class => local_name_for_exception

  ....   (block executed if given the exceptions have been raised )

rescue Exception_class,Exception_class => local_name_for_exception

  .... (block executed if given the exceptions have been raised )

else

  ...  block executed if no exception in main block

ensure

  .... block executed in any case
end

The rescue statement can give to the exception a local name, to be used in the rescue block itself.

The rescue block can have a "retry" statement which re-executes the block after the "begin" statement.

The optional block after the last rescue statement, defined by an "else" statement, is executed if there are no exceptions. If, in the main block, a return, next or break statement is encountered, the "else" block is skipped.

The final, optional, "ensure" block is executed in every case.

If a new exception is raised in a rescue block the old exception is discarded and replaced by the new exception.

Below some examples of the raise statement:

raise "message error" if n < 1

raise RuntimeError.new("message error") if n < 1

raise RuntimeError.exception("message error") if n < 1

An example of a simple "begin ... rescue .. end" block:

begin

  raise "negative value" if x<0     # raise the exceptions
  y=Math::sqrt(x)

rescue => ex                         # Stores the exception in the local variable ex

   puts "#{ex.class}: #{ex.message}" # Handle exception

end

In the following example more rescue blocks catch different exceptions; a single rescue block can catch more types of exceptions:

begin
  y=Math::sqrt(x)
rescue DomainError => ex
  puts "Try again with a value >= 1"
rescue TypeError,ArgumentError => ex
  puts "Try again with an integer"
end

The rescue statement can be also used to give an alternate value to a variable:

y = Math::sqrt(x) rescue 0

Postfix Expressions

In "postfix expressions" a condition is after the statements to be executed; postfix expressions are typical of Ruby, which tries to mimic a natural language with its syntax. The general form of a "postfix expressions" is:

     expr if  bool-expr      # the same as: "if expr then ... end" )

     expr unless bool-expr   # the same as "unless bool-expr then ... end")

Examples::

    exit if not str or not str[0]

    a=1 if a.nil?

There are postfix expressions also for the "while" and "until" loops, with condition and loop statements to be executed on the same line. In these cases the condition is tested before the first iteration:

x = 0
puts x = x + 1 while x < 10   # The while condition is at the end

a = [1,2,3]
puts a.pop until a.empty?     # The until condition is at the end