Introduction to Ruby

Program Structure

The character set of Ruby is 7-bit ASCII or UTF-8. It is a line-oriented language. Expressions and statements are terminated at the end of the line. To continue a state or expression on the next line a backslash is placed at the end of the line. Comments start with # and run to the end of the line. For block comments start with =begin at the start of the line and finish with =end on a new line. The logical end of a program can be denoted by __END__ at the start of a new line.

Basic Types

The basic types in Ruby are - numbers, strings, arrays, hashes, ranges, symbols, and regular expressions.

Integer and Floating Point Numbers

Ruby integers are objects of class Fixnum or Bignum. Fixnum objects hold integers that fit within the native machine word minus 1 bit. A Bignum holds an integer that is limited by available memory. Base indicators are 0 for octal, 0d for decimal, 0x for hex, 0b for binary. To get the integer value for an ACSII character precede it by a question mark. (?a = 97).

Strings

Strings are stored as sequences of 8-bit bytes. There are several ways in which String objects may be created.

Single-quoted string literals ('string' and %q/string/) undergo the least substitution. Double-quoted strings ("string", %Q/string/, and %/string/) undergo additional substitution. Strings can run across multiple lines. To do so, start the String with the sequence <<Identifier. The String is built from the next logical input lines and the building process stops when it meets the Identifier on a new line.

Ranges

A range is an interval with a start and end. Ranges are constructed with s..e and s...e. The double dots indicate an inclusive range and the triple dots indicate that e is not included in the range.

Arrays

Arrays are created by placing comma-separated objects in square brackets. Array of strings can be constructed using the short cut notations %w and %W.

Hashes

A hash is a sequence of key / value pairs between curly braces separated either by a comma or the sequence =>. Strings are frequently used as keys. Ruby will duplicate the string and hash the copy as the key. Any changes now made to the original string will not affect the hash.

Symbols

A Ruby symbol is an identifier corresponding to a string of characters, often a name. The symbol for the name is constructed by preceding the name with a colon. Similarly the symbol for an arbitrary string literal is constructed by preceding the string with a colon. In other languages symbols are called atoms.

Regular Expressions

Names

Names are used to refer to constants, variables, methods, classes, and modules. The first character of a name distinguishes a name.

Reserved Words
_FILE_ _LINE_ BEGIN END alias
and begin break case class
def defined? do else elsif
end ensure false for if
in module next nil not
or redo rescue retry return
self super then true undef
unless until when while yield

Ruby allows methods to be called without parameters with no parentheses. This causes an ambiguity if a name is a variable or method call. To decide between the two, Ruby parses the source file and keeps track of the symbols that have been assigned. It assumes that these symbols are variables. When it subsequently comes across a symbol that could be a variable or method, it checks to see if there has been a prior assignment. If so it treats the symbol as a variable, otherwise it treats it as a method call.

Variables and constants in Ruby hold references to objects. Variables may hold references to objects of many different types. A constant is also a reference to an object. Ruby allows the internal state (values of attributes of the object) to be changed.

Constants defined within a class or module may be accessed anywhere within the class or module. Constants outside the class or module may be accessed using the scope operator (::) like so - ClassName::ConstantName.

Global variables are available throughout the program. Class variables are available throughout the body of the class and must be initialized before use. A class variable is shared among all instances of that class. Instance variables are available within instance methods throughout the class body. A local variable is created dynamically when it is first assigned. The scope of the local variable is the enclosing block.

Operators

Operator Precedence (high to low)
[] []= Element reference, element set
** Exponentiation
! ~ + - Not, complement, unary plus and minus
* / % Multiply, divide, and modulo
+ - Plus and minus
>> << Right and left shift
& Bitwise and
^ | Exclusive or and or
<= < > >= <=> == === != =~ !~ Comparison operators
&& Logical and
|| Logical or
.. ... Range inclusive and exclusive
? : Conditional operator if-then-else
= += -= *= /= %= **=
|= &= >>= <<= &&= ||=
Assignment
defined? Check if symbol is defined
not Logical negation
or and Logical composition
if unless while until Expression modifiers
begin / end Block expression

Expressions

Block Expressions

Expressions may be grouped between the begin and end tags. The value of the block expression is the value of the last expression executed.

begin
  body
end
Boolean Expressions

Ruby predefines false and nil to be treated as false in a boolean context. The operators &&, and, ||, or are short circuit operators. The word form (and, or, not) of the boolean operators have lower precedence than the symbolic form. The defined? operator returns nil if its argument is not defined.

Conditional Expressions
if boolean_expr [ then | : ]
  body
[ elsif boolean_expr [ then | : ]
    body ]
[ else
    body ]
end
unless boolean_expr [ then | : ]
  body
[ else
    body ]
end

The body of if gets executed if boolean_expr is true and false for unless.

boolean_expr ? expr1 : expr2

returns expr1 if boolean_expr is true and expr2 otherwise.
case
  when condition [ then | : ]
    body
  when condition [ then | : ]
    body
  [ else
      body ]
end
Loops
while boolean_expr [do | :]
  body
end

The while loop executes the body zero or more times as long as boolean_expr is true.

until boolean_expr [do | :]
  body
end

The until loop excutes the body zero or more times as long as boolean_expr is false.

for name in expression [do | :]
  body
end

break terminates the immediately enclosing loop. redo repeats the loop from the start without reevaluating the condition or fetching the next element. next skips to the end of the loop and starts the next iteration. retry restarts the loop, reevaluating the condition.

Method Definition

Methods are defined as follows:

def methodName [ ( [ arg [ = val], ...] ) ]
  body
end
The method name should start with a lower case character. A method definition may contain nested method definitions. A method definition may have zero or more arguments. Arguments are separated by commas, and the argument list maybe enclosed in parentheses. An argument maybe followed by an equals sign and an expression giving it a default value. A method is called by passing its name to a receiver. A return expression immediately exits a method.

Class Definition

A class is defined as follows:

class ClassName [ < SuperClass ]
  body
end
Objects of the class are created as follows:
objName = ClassName.new [ ( [ args, ... ] ) ]

Module Definitions

A module is a class that cannot be instantiated. A module may contain class and instance methods, and may define constants and class variables. Module methods are invoked using the Module object as a receiver and constants are accessed using the scope resolution operator (::).

module name
  body
end 
A module may be included in the definition of another module using the keyword include.

Exceptions

In Ruby exceptions are thrown using the keyword raise. Exceptions can be handled within the scope of a begin / end block by having a rescue clause. The block may have multiple rescue clauses.

If an else clause is present, its body is executed if no exceptions were raised in the code. Exceptions raised during the execution of the else clause are not captured by rescue clauses in the same block as the else.

If an ensure clause is present, its body is always executed as the block is exited.

begin
  code ...
[ rescue [parm, ...] [=> var ] [ then ]
    error handling code ... ]
[ else
    no exception code ... ]
[ ensure
    always executed code ... ]
end