A Concise Introduction to Ruby
Copyright ©2006, 2007 by David Matuszek

Prelude Comments Strings Ranges
Tools Names and scope of names Pseudo variables Arrays
Objects and classes Reserved words Operators Hashes
Methods Numbers Statement types Modules
Layout     Input/Output

Prelude

Ruby is a succinct, powerful, enjoyable language. That said, it must be noted that Ruby is not identical across platforms, newer versions are not always upwardly compatible with older versions, and resources are not always in complete agreement about the syntax, semantics, and conventions of the language. Nonetheless, any errors in this document are my responsibility.

Ruby is extremely dynamic. Anything the programmer has done, the programmer can revise, add to, or undo at any time. A primary design goal of Ruby is that it be fun to program in. This document describes the syntax of Ruby, but is too brief to convey good idiomatic usage of Ruby.

My main references are Ruby in a Nutshell: A Desktop Quick Reference by Yukihiro Matsumoto ("Matz"), and Programming Ruby: The Pragmatic Programmers' Guide by Dave Thomas. Ruby is the creation of Matz, but Dave Thomas is the main advocate and documenter.

Tools

Command-line Tools

ruby
This will read in and execute a program from the console. Not recommended.
irb
A complete Ruby shell; great for trying things interactively. You can use load "filename" to load predefined code, such as function definitions.
ri ClassName
Displays documentation for the class (in vi; to quit vi, type :q and hit Enter).

Other tools

RDoc
Produces documentation for your program.
RubyGems
Packs code for distribution
FreeRIDE
Simple IDE for Ruby development
RDT, Ruby Development Tools
Ruby plugin for Eclipse
RDT, Ruby Development Tools
Ruby plugin for Eclipse
NetBeans 6 mod 9
Full version includes Ruby IDE and JRuby

Objects and classes

Ruby is a completely object-oriented language--all values are objects. Hence messages such as -5.abs are legal.

A class defines a new type of object. Classes are defined as:

    class NameOfClass
      # variable and method definitions go here
    end

Class names must be capitalized.

If this same class is defined again, any new definitions are added to the class.

To create a new object of a given class, use object = NameOfClass.new. If the class has a method named initialize, that method will be called just after the object has been created. Parameters may be given to the new method, and those same parameters will be passed along to the initialize method.

Methods

Instance methods are defined as

    def method_name(parameter1, ..., parameterN)
        # statements
    end 

and called with

    instance.method_name(parameter1, ..., parameterN)

Class methods are defined as

    def NameOfClass.method_name(parameter1, ..., parameterN)
        # statementsend 

and called with

    NameOfClass.method_name(parameter1, ..., parameterN)

In all of the above, the parentheses are optional; however, in complex expressions the parentheses may be required for disambiguation.

There may be only one method with a given name in the same class. If a named method is defined more than once, the new definition replaces the old one.

A method may contain explicit return or return value statements. If a method terminates by reaching the end of the method, the value returned is the last value computed (which, for many types of statements, is nil).

Layout

Ruby is line-oriented: Each statement goes on a separate line. If a statement ends with an operator, comma, or backslash, it is continued on the next line. Semicolons can be used to separate multiple statements on a single line.

Standard indentation in Ruby is two spaces, not four as in Java.

If a line contains exactly the character sequence __END__ (two underlines on each side), with no whitespace, it ends the program. Any additional lines are data.

Comments

Comments start with a pound sign (#) and continue to the end of the line. Multiline comments are enclosed by =begin (starting in column 1) and =end (starting in column 1).

Names and scope of names

Variables and constants hold references to objects. Variables and constants do not have types; any variable name can reference any type of object. Capitalization conventions given below are enforced by Ruby.

"Constants" can be altered (!); doing so yields a warning message.

Identifier type Naming conventions Scope of names
Local variables

Begin with a lowercase letter or underscore and consist of letters, underscores, and/or digits. Underscores, not camelCase, are used to separate words. Example: best_value

Method names also follow this rule. Example: find_best_value

Local variables are available within the immediately enclosing block, method, class, module, or program.
Method parameters are local to the method.
Block parameters and variables first assigned in a block are local to the block, unless they are already in existence, in which case they are inherited.
Loops do not create scopes, so variables that first occur with a loop are local to the enclosing scope. (loop do...end is a method, not a loop.)
Method names Method names follow the same conventions as local variables. In addition, methods that return a boolean often end with ?, and those that modify their receiver often end with !. Examples: find_best_value, capitalize!, empty?

Instance methods are available on instances of the class in which they are defined.

Class methods can be defined with def self.method or with def ClassName.method.

Instance variables Begin with the @ sign followed by a lowercase letter. Underscores are used to separate words. Example: @best_value Instance variables are available only within instance methods of the class, and have a default initial value of nil.
Class variables Begin with @@. Example: @@number_of_instances Class variables are available throughout the immediately enclosing class. They must be initialized before use. Variables declared at the top level belong to the Object class.
Global variables Begin with $. Some (mostly deprecated) Ruby-defined variables consist of $ and a punctuation mark. Example: $> is a synonym for $stdout. Global variables are available everywhere, and have a default initial value of nil. It's usually not good style to define your own global variables.
Constants Value constants and constant object references use uppercase letters and underscores. Example: MAX_SIZE
Class names and module names begin with a capital and use CamelCase. Example: ChessBoard
Constants are declared in a class or module, but cannot be declared within a method. Outside the defining class or module, they may be accessed by classObject::constant or moduleObject::constant.

Reserved words

__FILE__ The name of the current source file.
__LINE__ The current line number in the current source file.
BEGIN {...} Declares a block to be run as the program is being loaded.
END {...} Declares a block to be run after the program has finished executing. Multiple END blocks are executed in reverse order.
alias Creates a new name for a method, operator, global variable, or regular expression backreference.
and Logical conjuction.
begin Creates a scope (up to end) for grouping expressions, often for exception handling.
break Exits a loop.
case Introduces a case ("switch" in C) statement.
Class Classes (defined by class) are objects of this type.
def Introduces a function definition (to end).
defined? Returns a description of its argument, or nil if the argument is not defined.
do Introduces a block (to end) and executes it.
else Used in if, case, and unless statements.
elsif Like else if, but does not require an extra end.
end Terminates several different kinds of code blocks.
ensure Introduces code to be executed whether or not an exception has occurred.
false Logical value.
for Introduces a loop.
if Introduces an if statement.
in Indicates the range of a for loop.
module Defines a module (like a class). Ends with end.
next Jumps to a loop's conditional. (In a for loop, its variable is incremented.)
nil The default, unitialized object. Also means "false."
not The logical negation operator.
or The logical disjunction operator.
redo Jumps to just after a loop's conditional. (In a for loop, its variable is not incremented.)
rescue Catches exceptions in begin...rescue...ensure...end.
retry Starts a loop again from the beginning; in rescue, restarts the begin block.
return Returns from a method.
self A variable that refers to "this" object.
super Calls the method of the same name in a superclass.
then Used after condition in if, unless, when.
true Logical value.
undef Undefines a method.
unless About the same as if not.
until

About the same as while not.

when Introduces a case clause.
while Loops as long as its condition is true.
yield Executes the block given as a parameter.

Numbers

Integers are decimal by default, but may begin with a base indicator: 0 for octal, 0b for binary, 0x for hexadecimal, or 0d for decimal. Integers may be any size (limited by available memory).

Prefixing a single character with ? gives that character's numeric value. For example, ?a is 97.

Floating-point (real) numbers contain a decimal point, an exponent (following an e), or both. There must be at least one digit before the decimal point and before the e.

For readability, numbers may contain underscores.

Strings

Strings contain ASCII, not Unicode, characters. Newlines may occur within strings. Adjacent strings are concatenated. There are a variety of ways to write literal strings.

Singly-quoted strings

Strings may be enclosed in single quotes ('). Within a singly-quoted string, the only escaped character is \' (single quote). Substitutions are not performed.

Strings may be enclosed with any almost any punctuation mark as a delimiter, prefixed by %q. Example: %q!Hello!. However, if the opening delimiter is (, [, {, or <, the closing delimiter is ), ], }, or >, respectively. These strings act as singly-quoted strings.

Doubly-quoted strings

Strings may be enclosed in double quotes ("). Within a doubly-quoted string, all escaped characters are recognized, and actual values are substituted for the general forms #{expression}and #{expression}. If the expression is a single variable beginning with $ or @, the braces may be omitted: #$var and #@var.

Strings may be enclosed with delimiters, prefixed by %Q. Example: %Q!Hello!. Delimiters are the same as for %q. These strings act as doubly-quoted strings.

Shell commands

Strings may be enclosed in backquotes (`), or any delimiter prefixed by %x. Delimiters are the same as for %q. Escaped characters and substitutions are allowed. The string is evaluated as a command to the underlying operating system, and the result of the command is returned as a string.

Here documents

"Here documents" are for multiline strings. A string may begin with <<delimiter, where the delimiter is any sequence not containing whitespace, and ends with the delimiter in the same column. A string may begin with <<-delimiter, in which case the closing delimiter may be indented.

The initial delimiter may be enclosed in single quotes, double quotes or backquotes, to specify how the string is to be treated. The default is to treat the string as doubly-quoted.

A few String methods

"Characters" are ASCII, not Unicode.

Method Description
<< Append another string or a character.
=~ Match the regular expression and return the position of the match, or nil if no match.
capitalize, capitalize! Upcase the first character and downcase all others.
center(length) Pad with spaces on either side to make a string of the given length.
chomp, chomp! Remove a newline from the end of the string, if one is present.
count(description...) Count the characters fitting at least one "description". A description is a character string, but can use ch1-ch2 and ^ (negation) as in regular expressions.
delete(description...), delete!(description...) Delete the characters fitting at least one "description" (see count).
downcase, downcase! Convert all letters to lowercase.
include?(s_or_c) Tests whether the string includes the given string or character.
index(pat [, offset]) Search for the first occurrence of the given string, character, or regular expression (starting from offset, if given) and return its position, or nil if not found.
ljust(length) Pad with spaces on the left to make a string of the given length.
rindex(pat [, limit]) Search for the last occurrence of the given string, character, or regular expression (starting at or before limit, if given) and return its position, or nil if not found.
rjust(length) Pad with spaces on the left to make a string of the given length.
strip, strip! Remove whitespace from both ends of the string.
swapcase, swapcase! Change the capitalization of all letters.
tr(from, to), tr!(from, to) Replace the characters in from with the corresponding characters in to. Both from and to may use ch1-ch2 notation, and from can start with ^ for negation.
upcase, upcase! Convert all letters to uppercase.

Pseudo-variables

self
Same as self in C++ or this in Java.
true, false
Same as in Java.
nil
Same as null in Java.
__FILE__
The name of the current source file.
__LINE__
The current line number in __FILE__.

Operators

Highest precedence operators are at the top.

Most operators are methods, hence can be redefined. This feature should be used with extreme care and forethought. "Nonmethods" cannot be redefined.

Operator Meaning
:: Same as dot (.) in Java. Nonmethod.
[ ]   [ ]= Element reference, element set
** Exponentiation
!   ~   +   - Not (nonmethod), complement, unary plus, unary minus
*   /   % Multiply, divide, modulo
+   - Add, subtract
<<   >> Left shift, right shift
& Bitwise and
|   ^ Bitwise or, bitwise exclusive or
<   <=   >=   > Less, less or equals, greater or equals, greater
<=>  ==  ===  !=  =~  !~ Comparison, equality, case equals, unequal, match, nonmatch
&& Logical and (short circuit, nonmethod)
|| Logical or (short circuit, nonmethod)
..   ... Inclusive range, exclusive range (nonmethod)
? : Ternary if-then-else (nonmethod)
=  +=  -=  *=  /=  **=  %=
&=  &&=  |=  ||=  <<=  >>=
Assignments (all nonmethods)
defined? Test if symbol is defined
not Logical negation (nonmethod)
or   and Logical or, logical and (both short circuit, both nonmethods)
if  unless  while  until Expression modifiers
begin   end Block expression

Statement types

Brackets, [ ], indicate that the enclosed part is optional. An ellipsis, ... , means that the preceding element may be repeated.

Many methods are practically indistinguishable from statements. Some of these are included in the following table.

Type Syntax and description Examples
=
+=, *=, etc.

variable = value
variables = values

Assignment. More than one value may be assigned at a time.

hi = "hello"

x, y = y, x

alias

alias new_name original_name

Creates a new name for a method, operator, global variable, or regular expression backreference.

alias display puts
begin
  ...
end
begin
  [code]
[rescue [exception, ...]
  [code]]
[ensure   # may be more than one
  [code]] 
end

begin introduces a new scope; variables seen for the first time inside a begin..end block are local to that scope.

begin...rescue...ensure is like Java's try...catch...finally.

begin
  eval string
rescue SyntaxError,
       NameError => boom
  print "Can't compile:" + boom
rescue StandardError => bang
  print "Script error:" + bang
end
break
break [expression]
Exits a loop. If used within a block, the value of the expression is the value of the loop.
break
case
case expression
[when expression[, expression...][then]
  code]...
[else
  code]
end

Comparisons are done using ===.

when expressions are separated from code by newlines, semicolons, or the word then.

case i
when 1, 3, 5 then puts "odd"
when 2, 4
  puts "even"
else puts "too big"
end
class
class ClassName [< SuperClass]
  code
end

The ClassName must be a constant. Classes introduce a new scope for local variables.

A class definition may be repeated (the SuperClass must match or be omitted); the new content is added to the existing class.

class Something
  puts "whatever"
end
do
  ...
end
method_call do [|parameter, ...|]|
  [code]
end
Introduces a block, optionally passing parameters into the block. The yield statement will return values from the block.
array.each do |element|
  puts element
end 
method_call { [|parameter, ...|] [code] }
Braces may be used in place of do...end.
array.each { |e| puts e } 
each

expression.each block

The method each iterates through the values in the expression. The Array, Set, Hash, and Range classes, among others, all supply an each method.

my_set.each do |element|
  puts element
end 
for
for var[, var...] in expression [do]
  code
end
Ruby's for loop is less flexible than in C.
for i in 1..10
  puts "#{i} --> #{i * i}"
end
if
if condition [then]
  code
[elsif condition [then]
  code]
[else
  code]
end
Conditions are separated from code by newlines, semicolons, or the word then.
if count == 0   
  puts 'yes'
elsif count > 0 
  puts 'no'
else
  puts 'maybe'
end

if count==0; puts 'yes'; end
statement if condition
puts 'yes' if count == 0
loop

loop block

Loops until a break is executed.

loop do
  c *= 2
  break if c > 1000
end 
next
next

Within a loop, jumps to just before the loop test.
Within a block, exits the block with nil.

next
raise

raise

Within a rescue clause, re-raises the same exception again; otherwise, raises RuntimeError.

raise

raise string

Raises a RuntimeError with this message.

raise "You goofed!"

raise exception [, string [stack_trace]]

Raises an error of the given type, optionally with the given message and stack trace.

raise NameError, "Oops"
redo
redo

Within a loop, restarts the loop body, but does not reevaluate the condition or get the next iterated element.

Within a block, restarts the yield or call.

redo
require

require string

The string must be the name of a Ruby file; the .rb extension is optional.

require 'chess_board.rb'
rescue
rescue ExceptionType, ... [=> variable]
The rescue clause is used to catch raised exceptions, of the given ExceptionType or any subtype thereof. It can be used (1) in a method, (2) within a begin...end block, and (3) as a statement suffix. The variable, if present, will hold the exception object; it is also in the special variable $!.
rescue Exception => e
retry
retry
Within a loop, restarts the loop body after reevaluating the condition or getting the next iterated element.
retry
unless
unless condition [then]
  code
[else
  code]
end
Like an if statement with the condition negated.
unless foo == ''
  puts foo
end
statement unless condition
puts foo unless foo == ''
until
until condition [do]
  code
end

Like a while statement with the condition negated.

The condition is separated from the code by do, a newline, or a semicolon.

until count > 100 do
  count *= 2
end
statement until condition
count *= 2 until count > 100
begin
  code
end untilcondition

In this form, if the begin does not contain rescue or ensure clauses, the code will be executed at least once before the condition is tested.

begin
  count *= 2
end until count > 100
while
while condition [do]
  code
end
The condition is separated from the code by do, a newline,or a semicolon.
while count < 100
  count *= 2
end
statement while condition
count *= 2 while count < 100
begin
  code
end while condition

In this form, if the begin does not contain rescue or ensure clauses, the code will be executed at least once before the condition is tested.

begin
  count *= 2
end while count < 100
yield
yield [value, ...]

Returns zero or more values from a block.

yield result

Ranges

A range is a sequence of integers. The two-dot form, min..max, includes both endpoints; the three-dot form, min...limit, includes min but not limit.

Arrays

An array is a sequence of values indexed by integers; the first location in the array is location 0 (zero). Negative integers can be used to index the array from the other end; -1 is the last location in the array. The values in an array may be of different types. Example:

0
1
2
3
4
"ace" 250 3.14 "hi!" :abc
-5
-4
-3
-2
-1

Arrays may be created by enclosing comma-separated values in square brackets; a final trailing comma is ignored. For example, you can create the above array with

my_array = [ "ace", 250, 3.14, "hi!", :abc ]

An easy way to create an array of strings is with %w (for singly-quoted strings) or %W (for doubly quoted strings). Example:

words = %w( apple banana cherry )

You can also create an array with Array.new.

Any (reasonable) integer can be used as an array index. If you read from an array location that hasn't been used, you get nil; if you write to a previously unused location, it will be created. For example, the following sequence is perfectly legal, and prints three nils and an abc.:

a = Array.new; a[3] = "abc"; a.each { |v| puts v }

If you index into an array with a pair of numbers, a[start, count], you get a new array of count values copied from a, starting from start. If you index with a range, a[min..max], you get a new array of those values copied from a.

Some of the more useful array methods are each, push, pop, sort, sort!, and join.

Hashes

A hash is a mapping of keys to values. Any object that responds to the hash and eql? messages can be used as a key; objects that are eql? must have the same hash code. Immutable objects, such as symbols, make the best keys..

A hash may be created by enclose comma-separated key => value pairs inside braces; for example,

my_hash = { :ace => 1, :jack => 11, :queen => 12, :king => 13 }

Hashes may be "indexed" by a key within brackets, for example, my_hash[:jack] gives 11. If the key does not exist in the hash, nil is returned as the value. New key-value pairs may be added to hashes, for example, my_hash[:foo] = :bar.

The order of key-value pairs in a hash is essentially random.

Modules

A module is defined like a class, and may define class methods, instance methods, instance variables, and constants:

module ModuleName
  expressions
end

Unlike a class, you cannot create an instance of a module.

There are two ways to use modules:

Input/Output

Interactive I/O

print
Prints its argument without a newline. Example: print 'Enter a number: '
puts
Prints its argument with a newline. Example: puts "I read: #{input}"
printf
The first argument is a format string (as in C), while the remaining arguments are values to be inserted into the format string. Example: printf("Float: %5.2f, int: %i, string: %s", 3.1416, 17, 'foo')
STDOUT.flush
A method used to flush output. Should be used before interactive input. Example: print 'Gimme a number: '; STDOUT.flush; number = gets
file.sync = true
Turns on autoflushing for the specified file.
gets
Reads a line of input from the console, as a string.
 

File I/O

Command line arguments:

Directory functions:

File functions:

Examples:

Program Output
ARGV.each { |arg| puts "arg -> #{arg}" }
puts "pwd -> #{Dir.pwd}"
Dir.foreach(".")  { |file| puts "file -> #{file}" }
Dir.mkdir("goofus", 0755) unless File.exists?  "goofus"

if File.exists?  "goofus"
  Dir.chdir("goofus")
  puts "pwd -> #{Dir.pwd}"
    
  puts "  File 'goofus' created"
  puts "  readable? #{File.readable? "goofus"}"
  puts "  writable? #{File.writable? "goofus"}"
  puts "  executable? #{File.executable? "goofus"}"
  puts "  file? #{File.file? "goofus"}"
  puts "  directory? #{File.directory? "goofus"}"
  
  f = File.new("doofus", "w")
  f.puts "Line one", "Line two"
  f.close # it's important to close the file!

  File.open "doofus" do |f2|
    f2.each_line { |line| puts line }
  end # the block form automatically closes the file

  File.delete("doofus")
  puts "  'doofus' deleted" unless File.exists?  "doofus"
end
 
Dir.chdir("..")
puts "pwd -> #{Dir.pwd}"

Dir.rmdir("goofus") if File.exists?  "goofus"
puts "  'goofus' deleted" unless File.exists?  "goofus"
arg ->arg -> hello
arg -> 123
pwd -> C:/Workspace/RubyTests
file -> .
file -> ..
file -> .loadpath
file -> .project
file -> io_tests.rb
pwd -> C:/Workspace/RubyTests/goofus
  File 'goofus' created
  readable? false
  writable? false
  executable? false
  file? false
  directory? false
Line one
Line two
  'doofus' deleted
pwd -> C:/Workspace/RubyTests
  'goofus' deleted