These are some very rough/sketchy notes that I took while doing the
exercises on the introductory track of the Ruby language at
codeacademy. They were written from the point-of-view of an amateur
programmer in C and Python (read: "me").

Since this is my first time with Ruby and I only have about 1 week of
experience with it, these notes are likely to contain many mistakes, many
simplifications, many omissions or simply gross errors. I would love to be
informed of such facts so that I can fix them and not write code that is
burdensome for others to maintain.

Interpolation is performed by putting the name name of the variable
inside a string and delimited as #{name} at the place we want the
interpolation to occur.

Methods like .capitalize don't change the string (they return a new
string capitalized). To change the string, you call the method
.capitalize! (with a ! at the end of the name of the method).

Other useful methods: .gsub for globally substituting a regular
expression (and its variant .gsub! for inplace modification), and
.include? to verify if the first string includes another.

Another method: .split(" "), to split on the string specified as
argument.

Control flow

If

The syntax of a if is:

if expression1
block1
elsif expression2
block2
else
block3
end

note that it ends with the word end, there are no need for parentheses,
no braces, no colons, and the keyword for "else if" is elsif (different
from Python's elif).

The "if" can also be started with the keyword unless instead, which
checks if the expression is false rather than true (as is the case of
if).

While

The syntax of the while is similar to other languages:

while condition
block
end

A variation of the while is the until, with the same syntax, except
for the until in place of the while, and that it iterates when the
condition is false, instead of true.

For

The simple case of iterating over a range of numbers is:

for i in 1...10
block
end

Like ranges in Python, the 10 is not included (the variable i iterates
from 1 to 9).

For an inclusive range, we use two dots (1..10), instead of three
dots (1...10).

Loop

To iterate a block, we can use the loop keyword, as in:

loop { block } # with braces

or as in

loop do # note the pair do/end in place of braces
block
end

It is useful to use break when using loop to break out of the infinite
iterations.

Similarly, we can use next as in other languages (the same as continue
in C or C++).

Arrays

The equivalent to Python's lists are arrays and they are declared in the
same fashion:

my_array = [1, 2, 3, 4, 5]

Arrays in Ruby are 0-based.

Every array has an iterator called the .each method. The basic syntax
is:

object.each { |item| block } # do something

which can be written as:

object.each do |item| block end

where the name between | | is bound to (a copy of?) each element of
object in turn. The equivalent in Python would be:

for item in object:
block

Arrays can be sorted with the .sort method (or its sibling .sort!).
When passing a parameter, it is useful to use the spaceship operator
(<=>) (like Perl) to specify a custom order (similar in spirit to what
we do with Python's key argument to the sort method of a list).
Example:

The .push method appends an element to an Array (similar to Python's
.append).

The empty Array is denoted by [], like an empty list in Python.

An iterator (like (1..10)) can be converted to an array with the .to_a
method.

Hashes

A literal hash is defined by the syntax:

my_hash = {
"key1" => "abc",
"key2" => 2,
"key3" => false
}

Quite similar to the version in Python:

my_hash = {
"key1": "abc",
"key2": 2,
"key3": False
}

In fact, in Ruby 1.9, you can write, instead:

my_hash = {
key1: "abc",
key2: 2,
key3: false
}

which is very similar to Python or JSON.

The empty hash, OTOH, is defined by calling the constructor .new of the
class Hash:

my_hash = Hash.new

The syntax used by Python can also be used: my_hash = {}

Iterating over a hash is done the same way as done for an array, but the
.each method gives both the key and the value, as in:

my_hash.each do |k, v|
puts "#{k}: #{v}"
end

To iterate only on keys, we use the method .each_key. To iterate only on
values, we use the method .each_value.

A hash can be sorted with the .sort_by method (to sort by keys, values
or any expression involving them) and since it can be ordered, we can
reverse (in-place) the order of its elements with the .reverse! method.
This makes Ruby's hashes to "taste" like Python's OrderedDict's.

When one initializes a hash, one can specify a default value to the .new
method (e.g., foo = Hash.new(0)), which makes it convenient to do the
equivalent of Python's defaultdict or Counter.

You can select part of a hash by using the .select method and giving it
a block. For example:

good_movies = movie_ratings.select{|k, v| v > 3}

Functions/methods

Functions in Ruby are defined with the word def (as in Python) and end
with the word end, as other composite constructs. Example:

def square(n)
return n*n
end

Parentheses are optional in Ruby, unless they create ambiguity. So, to
call the function above, one can use any of the following:

square(2)
square 2

A function can take a block as a parameter (and this is what .each does,
for instance).

Functions can take a variable number of elements with the splash
operator (denoted by *), which puts the extra parameters in an Array
(like Python).

Functions can have default parameters, which are set in the "prototype",
just like in Python or C++.

If the return keyword is omitted from the method, Ruby uses an implicit
return, where the value of the last executed expression is returned to the
caller of the method.

Symbols

Any instances of a given symbol share the same ID. This is due to the fact
that they are immutable.

Symbols start with a colon (:) and they can contain any character that
is valid for a variable name.

It is possible to convert between a symbol and a string with the methods
.to_s and .to_sym.

Comments

Single line comments use the hash symbol (#).

Ruby also has multiline comments, which are delimited by a line beginning
with =begin and a line beginning with =end.

Lambda functions

A lambda function in Ruby is defined, as expected, as, for example:

foo = lambda { |x| x.to_sym }

The basic differences between a lambda and a proc is that:

A lambda checks the number of elements that it receives, while a proc
doesn't and assigns nil to parameters that it didn't receive (a proc
seems to ignore extra parameter that it wasn't expecting).

When a lambda returns, the control goes back to the function that called
the lambda, while when a proc returns, the control is returned also
from the function that called the proc.

Classes

"Everything is an object in Ruby." (At least one exception are blocks).

To test if an object is of a given class, you use the method .is_a? on
the object and the type as argument (e.g., foo.is_a? Integer)

The "null" value in Ruby is nil. It is equivalent to None in Python.

The only "falsy" values in Ruby are false and nil. The others are
"truthy", differently from C/C++/Perl/Python.

For a given object, the method .object_id returns what is the "address"
of that object.

Classes in Ruby are created with the syntax

class ClassExample
# body
end

(That is for a class that has is not derived from other regular classes).

Constructors in Ruby are called initialize. An instance of a class is
created by calling the method .new on the class name (and passing
parameters as needed for the initialize method).

Instance variables are named with 1 at sign (@) as a prefix. Class
variables are named with 2 at signs (@@) as a prefix. Global variables
are named with a dollar sign ($) as a prefix.

Class methods are declared inside a class prefixed with self. and they
are called with the class name suffixed with the name of the method. For
example, for a class MyClass, with a class method class_method, we
call it as MyClass.class_method.

When overriding a method in a subclass, one can call the method from the
parent class with the keyword super, as in super(arg1, arg2).

Ruby doesn't support multiple inheritance. In place of multiple
inheritance, Ruby offers mixins.

To access one attribute, say @my_attrib, in Ruby classes, one usually
creates two methods to manipulate it: a method with the name my_attrib,
that returns the value of @my_attrib (a getter) and a method with the
name my_attrib= that accepts a parameter to set @my_attrib to (a
setter).

There is syntatic sugar for creating both getters or setters.

For a getter, you declare attr_reader :my_attrib (the member name as a
symbol).

For a setter, you declare attr_writer :my_attrib.

If you need both a getter and a setter, then you can abbreviate them with
attr_accessor.

All methods, by default, are public in Ruby. To explicitly mark something
as public, you use the keyword public. To mark something as private, you
use the keyword private.

Modules

You can import a module with the keyword require (as in Perl) and the
name of the module in quotes.

One example of a module is the benchmark module, which provides the
Benchmark class, which has the method .realtime, which takes a block
and reports how much time it used.

To create a module, use a syntax similar to that of a class, but
substituting the keyword class with module.

The scope resolution operator in Ruby is the double colon (::), like in
Perl.

To create a method inside a module, you have to prefix it by the name of
the module with a dot or with self., if you want to create a method to
be called outside the module.

The same also holds for creating class methods (as opposed to instance
methods): they can be simply named self.foo to get a class method called
foo.

While some modules are already "preloaded" by the interpreter (e.g.,
Math), others need to be explicitly loaded. We do this by using require
'foo' to load the module (in the file foo?).

Mixins

A mixin is the use of a module to "enrich" a class, adding "instance"
methods of the module to the class.

It is, in a sense, a way to have some of multiple inheritance in Ruby
(without its headaches?)

Using the word include Foo imports the items of the module Foo in the
current namespace for instances of a class.

Using the word extend Foo imports the items of the module Foo in the
current namespace as class methods/attributes.

Conventions

Local variables are named in lower case, with parts separated by
underscores, as in my_name.

Methods that return boolean values have a question mark (?) at the end
of their name.

Methods that have destructive side-effects (like changing their input)
have an exclamation mark (!) at the end of their name.

Code is indented by 2 spaces.

Like other languages, constants are written in all caps, with words
separated by underscores. For example, MAX_VALUE.

Global variables are prefixed with a dollar sign (e.g., $Foo).

Classes are named in camel case (no initial lowercase).

The "poetic mode" in Ruby recommends one to omit the parentheses on
function calls (whenever unambiguous) and, in essence, to write as little
"bureaucracy" (like the explicit return keyword in methods).